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 #define DPRINTF(fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0)
48 #define DPRINTF(fmt, ...) do { } while (0)
56 #define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
57 #define VID 0x03 /* MPIC version ID */
59 /* OpenPIC capability flags */
60 #define OPENPIC_FLAG_IDE_CRIT (1 << 0)
62 /* OpenPIC address map */
63 #define OPENPIC_GLB_REG_START 0x0
64 #define OPENPIC_GLB_REG_SIZE 0x10F0
65 #define OPENPIC_TMR_REG_START 0x10F0
66 #define OPENPIC_TMR_REG_SIZE 0x220
67 #define OPENPIC_MSI_REG_START 0x1600
68 #define OPENPIC_MSI_REG_SIZE 0x200
69 #define OPENPIC_SRC_REG_START 0x10000
70 #define OPENPIC_SRC_REG_SIZE (MAX_SRC * 0x20)
71 #define OPENPIC_CPU_REG_START 0x20000
72 #define OPENPIC_CPU_REG_SIZE 0x100 + ((MAX_CPU - 1) * 0x1000)
75 #define RAVEN_MAX_CPU 2
76 #define RAVEN_MAX_EXT 48
77 #define RAVEN_MAX_IRQ 64
78 #define RAVEN_MAX_TMR MAX_TMR
79 #define RAVEN_MAX_IPI MAX_IPI
81 /* Interrupt definitions */
82 #define RAVEN_FE_IRQ (RAVEN_MAX_EXT) /* Internal functional IRQ */
83 #define RAVEN_ERR_IRQ (RAVEN_MAX_EXT + 1) /* Error IRQ */
84 #define RAVEN_TMR_IRQ (RAVEN_MAX_EXT + 2) /* First timer IRQ */
85 #define RAVEN_IPI_IRQ (RAVEN_TMR_IRQ + RAVEN_MAX_TMR) /* First IPI IRQ */
86 /* First doorbell IRQ */
87 #define RAVEN_DBL_IRQ (RAVEN_IPI_IRQ + (RAVEN_MAX_CPU * RAVEN_MAX_IPI))
90 #define FSL_MPIC_20_MAX_CPU 1
91 #define FSL_MPIC_20_MAX_EXT 12
92 #define FSL_MPIC_20_MAX_INT 64
93 #define FSL_MPIC_20_MAX_IRQ MAX_IRQ
95 /* Interrupt definitions */
96 /* IRQs, accessible through the IRQ region */
97 #define FSL_MPIC_20_EXT_IRQ 0x00
98 #define FSL_MPIC_20_INT_IRQ 0x10
99 #define FSL_MPIC_20_MSG_IRQ 0xb0
100 #define FSL_MPIC_20_MSI_IRQ 0xe0
101 /* These are available through separate regions, but
102 for simplicity's sake mapped into the same number space */
103 #define FSL_MPIC_20_TMR_IRQ 0x100
104 #define FSL_MPIC_20_IPI_IRQ 0x104
107 * Block Revision Register1 (BRR1): QEMU does not fully emulate
108 * any version on MPIC. So to start with, set the IP version to 0.
110 * NOTE: This is Freescale MPIC specific register. Keep it here till
111 * this code is refactored for different variants of OPENPIC and MPIC.
113 #define FSL_BRR1_IPID (0x0040 << 16) /* 16 bit IP-block ID */
114 #define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */
115 #define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */
117 #define FREP_NIRQ_SHIFT 16
118 #define FREP_NCPU_SHIFT 8
119 #define FREP_VID_SHIFT 0
121 #define VID_REVISION_1_2 2
122 #define VID_REVISION_1_3 3
124 #define VENI_GENERIC 0x00000000 /* Generic Vendor ID */
126 #define GLBC_RESET 0x80000000
128 #define TIBC_CI 0x80000000 /* count inhibit */
129 #define TICC_TOG 0x80000000 /* toggles when decrement to zero */
131 #define IDR_EP_SHIFT 31
132 #define IDR_EP_MASK (1 << IDR_EP_SHIFT)
133 #define IDR_CI0_SHIFT 30
134 #define IDR_CI1_SHIFT 29
135 #define IDR_P1_SHIFT 1
136 #define IDR_P0_SHIFT 0
138 #define MSIIR_OFFSET 0x140
139 #define MSIIR_SRS_SHIFT 29
140 #define MSIIR_SRS_MASK (0x7 << MSIIR_SRS_SHIFT)
141 #define MSIIR_IBS_SHIFT 24
142 #define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT)
144 #define BF_WIDTH(_bits_) \
145 (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
147 static inline void set_bit(uint32_t *field
, int bit
)
149 field
[bit
>> 5] |= 1 << (bit
& 0x1F);
152 static inline void reset_bit(uint32_t *field
, int bit
)
154 field
[bit
>> 5] &= ~(1 << (bit
& 0x1F));
157 static inline int test_bit(uint32_t *field
, int bit
)
159 return (field
[bit
>> 5] & 1 << (bit
& 0x1F)) != 0;
162 static int get_current_cpu(void)
164 return cpu_single_env
->cpu_index
;
167 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
169 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
170 uint32_t val
, int idx
);
172 typedef struct IRQ_queue_t
{
173 uint32_t queue
[BF_WIDTH(MAX_IRQ
)];
176 int pending
; /* nr of pending bits in queue */
179 typedef struct IRQ_src_t
{
180 uint32_t ipvp
; /* IRQ vector/priority register */
181 uint32_t ide
; /* IRQ destination register */
183 int pending
; /* TRUE if IRQ is pending */
186 #define IPVP_MASK_SHIFT 31
187 #define IPVP_MASK_MASK (1 << IPVP_MASK_SHIFT)
188 #define IPVP_ACTIVITY_SHIFT 30
189 #define IPVP_ACTIVITY_MASK (1 << IPVP_ACTIVITY_SHIFT)
190 #define IPVP_MODE_SHIFT 29
191 #define IPVP_MODE_MASK (1 << IPVP_MODE_SHIFT)
192 #define IPVP_POLARITY_SHIFT 23
193 #define IPVP_POLARITY_MASK (1 << IPVP_POLARITY_SHIFT)
194 #define IPVP_SENSE_SHIFT 22
195 #define IPVP_SENSE_MASK (1 << IPVP_SENSE_SHIFT)
197 #define IPVP_PRIORITY_MASK (0xF << 16)
198 #define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
199 #define IPVP_VECTOR(opp, _ipvpr_) ((_ipvpr_) & (opp)->vector_mask)
201 /* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */
202 #define IDE_EP 0x80000000 /* external pin */
203 #define IDE_CI 0x40000000 /* critical interrupt */
205 typedef struct IRQ_dst_t
{
206 uint32_t pctp
; /* CPU current task priority */
208 IRQ_queue_t servicing
;
212 typedef struct OpenPICState
{
216 /* Behavior control */
221 uint32_t veni
; /* Vendor identification register */
222 uint32_t vector_mask
;
229 MemoryRegion sub_io_mem
[5];
231 /* Global registers */
232 uint32_t frep
; /* Feature reporting register */
233 uint32_t glbc
; /* Global configuration register */
234 uint32_t pint
; /* Processor initialization register */
235 uint32_t spve
; /* Spurious vector register */
236 uint32_t tifr
; /* Timer frequency reporting register */
237 /* Source registers */
238 IRQ_src_t src
[MAX_IRQ
];
239 /* Local registers per output pin */
240 IRQ_dst_t dst
[MAX_CPU
];
242 /* Timer registers */
244 uint32_t ticc
; /* Global timer current count register */
245 uint32_t tibc
; /* Global timer base count register */
247 /* Shared MSI registers */
249 uint32_t msir
; /* Shared Message Signaled Interrupt Register */
257 static void openpic_irq_raise(OpenPICState
*opp
, int n_CPU
, IRQ_src_t
*src
);
259 static inline void IRQ_setbit(IRQ_queue_t
*q
, int n_IRQ
)
262 set_bit(q
->queue
, n_IRQ
);
265 static inline void IRQ_resetbit(IRQ_queue_t
*q
, int n_IRQ
)
268 reset_bit(q
->queue
, n_IRQ
);
271 static inline int IRQ_testbit(IRQ_queue_t
*q
, int n_IRQ
)
273 return test_bit(q
->queue
, n_IRQ
);
276 static void IRQ_check(OpenPICState
*opp
, IRQ_queue_t
*q
)
285 /* IRQ bitmap is empty */
289 for (i
= 0; i
< opp
->max_irq
; i
++) {
290 if (IRQ_testbit(q
, i
)) {
291 DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
292 i
, IPVP_PRIORITY(opp
->src
[i
].ipvp
), priority
);
293 if (IPVP_PRIORITY(opp
->src
[i
].ipvp
) > priority
) {
295 priority
= IPVP_PRIORITY(opp
->src
[i
].ipvp
);
302 q
->priority
= priority
;
305 static int IRQ_get_next(OpenPICState
*opp
, IRQ_queue_t
*q
)
315 static void IRQ_local_pipe(OpenPICState
*opp
, int n_CPU
, int n_IRQ
)
321 dst
= &opp
->dst
[n_CPU
];
322 src
= &opp
->src
[n_IRQ
];
323 priority
= IPVP_PRIORITY(src
->ipvp
);
324 if (priority
<= dst
->pctp
) {
325 /* Too low priority */
326 DPRINTF("%s: IRQ %d has too low priority on CPU %d\n",
327 __func__
, n_IRQ
, n_CPU
);
330 if (IRQ_testbit(&dst
->raised
, n_IRQ
)) {
332 DPRINTF("%s: IRQ %d was missed on CPU %d\n",
333 __func__
, n_IRQ
, n_CPU
);
336 src
->ipvp
|= IPVP_ACTIVITY_MASK
;
337 IRQ_setbit(&dst
->raised
, n_IRQ
);
338 if (priority
< dst
->raised
.priority
) {
339 /* An higher priority IRQ is already raised */
340 DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n",
341 __func__
, n_IRQ
, dst
->raised
.next
, n_CPU
);
344 IRQ_get_next(opp
, &dst
->raised
);
345 if (IRQ_get_next(opp
, &dst
->servicing
) != -1 &&
346 priority
<= dst
->servicing
.priority
) {
347 DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
348 __func__
, n_IRQ
, dst
->servicing
.next
, n_CPU
);
349 /* Already servicing a higher priority IRQ */
352 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU
, n_IRQ
);
353 openpic_irq_raise(opp
, n_CPU
, src
);
356 /* update pic state because registers for n_IRQ have changed value */
357 static void openpic_update_irq(OpenPICState
*opp
, int n_IRQ
)
362 src
= &opp
->src
[n_IRQ
];
366 DPRINTF("%s: IRQ %d is not pending\n", __func__
, n_IRQ
);
369 if (src
->ipvp
& IPVP_MASK_MASK
) {
370 /* Interrupt source is disabled */
371 DPRINTF("%s: IRQ %d is disabled\n", __func__
, n_IRQ
);
374 if (IPVP_PRIORITY(src
->ipvp
) == 0) {
375 /* Priority set to zero */
376 DPRINTF("%s: IRQ %d has 0 priority\n", __func__
, n_IRQ
);
379 if (src
->ipvp
& IPVP_ACTIVITY_MASK
) {
380 /* IRQ already active */
381 DPRINTF("%s: IRQ %d is already active\n", __func__
, n_IRQ
);
386 DPRINTF("%s: IRQ %d has no target\n", __func__
, n_IRQ
);
390 if (src
->ide
== (1 << src
->last_cpu
)) {
391 /* Only one CPU is allowed to receive this IRQ */
392 IRQ_local_pipe(opp
, src
->last_cpu
, n_IRQ
);
393 } else if (!(src
->ipvp
& IPVP_MODE_MASK
)) {
394 /* Directed delivery mode */
395 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
396 if (src
->ide
& (1 << i
)) {
397 IRQ_local_pipe(opp
, i
, n_IRQ
);
401 /* Distributed delivery mode */
402 for (i
= src
->last_cpu
+ 1; i
!= src
->last_cpu
; i
++) {
403 if (i
== opp
->nb_cpus
)
405 if (src
->ide
& (1 << i
)) {
406 IRQ_local_pipe(opp
, i
, n_IRQ
);
414 static void openpic_set_irq(void *opaque
, int n_IRQ
, int level
)
416 OpenPICState
*opp
= opaque
;
419 src
= &opp
->src
[n_IRQ
];
420 DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
421 n_IRQ
, level
, src
->ipvp
);
422 if (src
->ipvp
& IPVP_SENSE_MASK
) {
423 /* level-sensitive irq */
424 src
->pending
= level
;
426 src
->ipvp
&= ~IPVP_ACTIVITY_MASK
;
429 /* edge-sensitive irq */
433 openpic_update_irq(opp
, n_IRQ
);
436 static void openpic_reset(DeviceState
*d
)
438 OpenPICState
*opp
= FROM_SYSBUS(typeof (*opp
), sysbus_from_qdev(d
));
441 opp
->glbc
= GLBC_RESET
;
442 /* Initialise controller registers */
443 opp
->frep
= ((opp
->nb_irqs
- 1) << FREP_NIRQ_SHIFT
) |
444 ((opp
->nb_cpus
- 1) << FREP_NCPU_SHIFT
) |
445 (opp
->vid
<< FREP_VID_SHIFT
);
448 opp
->spve
= -1 & opp
->vector_mask
;
449 opp
->tifr
= opp
->tifr_reset
;
450 /* Initialise IRQ sources */
451 for (i
= 0; i
< opp
->max_irq
; i
++) {
452 opp
->src
[i
].ipvp
= opp
->ipvp_reset
;
453 opp
->src
[i
].ide
= opp
->ide_reset
;
455 /* Initialise IRQ destinations */
456 for (i
= 0; i
< MAX_CPU
; i
++) {
457 opp
->dst
[i
].pctp
= 15;
458 memset(&opp
->dst
[i
].raised
, 0, sizeof(IRQ_queue_t
));
459 opp
->dst
[i
].raised
.next
= -1;
460 memset(&opp
->dst
[i
].servicing
, 0, sizeof(IRQ_queue_t
));
461 opp
->dst
[i
].servicing
.next
= -1;
463 /* Initialise timers */
464 for (i
= 0; i
< MAX_TMR
; i
++) {
465 opp
->timers
[i
].ticc
= 0;
466 opp
->timers
[i
].tibc
= TIBC_CI
;
468 /* Go out of RESET state */
472 static inline uint32_t read_IRQreg_ide(OpenPICState
*opp
, int n_IRQ
)
474 return opp
->src
[n_IRQ
].ide
;
477 static inline uint32_t read_IRQreg_ipvp(OpenPICState
*opp
, int n_IRQ
)
479 return opp
->src
[n_IRQ
].ipvp
;
482 static inline void write_IRQreg_ide(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
486 tmp
= val
& (IDE_EP
| IDE_CI
);
487 tmp
|= val
& ((1ULL << MAX_CPU
) - 1);
488 opp
->src
[n_IRQ
].ide
= tmp
;
489 DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ
, opp
->src
[n_IRQ
].ide
);
492 static inline void write_IRQreg_ipvp(OpenPICState
*opp
, int n_IRQ
, uint32_t val
)
494 /* NOTE: not fully accurate for special IRQs, but simple and sufficient */
495 /* ACTIVITY bit is read-only */
496 opp
->src
[n_IRQ
].ipvp
= (opp
->src
[n_IRQ
].ipvp
& IPVP_ACTIVITY_MASK
) |
497 (val
& (IPVP_MASK_MASK
| IPVP_PRIORITY_MASK
| opp
->vector_mask
));
498 openpic_update_irq(opp
, n_IRQ
);
499 DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ
, val
,
500 opp
->src
[n_IRQ
].ipvp
);
503 static void openpic_gbl_write(void *opaque
, hwaddr addr
, uint64_t val
,
506 OpenPICState
*opp
= opaque
;
510 DPRINTF("%s: addr " TARGET_FMT_plx
" <= %08x\n", __func__
, addr
, val
);
514 case 0x00: /* Block Revision Register1 (BRR1) is Readonly */
524 openpic_cpu_write_internal(opp
, addr
, val
, get_current_cpu());
526 case 0x1000: /* FREP */
528 case 0x1020: /* GLBC */
529 if (val
& GLBC_RESET
) {
530 openpic_reset(&opp
->busdev
.qdev
);
533 case 0x1080: /* VENI */
535 case 0x1090: /* PINT */
536 for (idx
= 0; idx
< opp
->nb_cpus
; idx
++) {
537 if ((val
& (1 << idx
)) && !(opp
->pint
& (1 << idx
))) {
538 DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx
);
539 dst
= &opp
->dst
[idx
];
540 qemu_irq_raise(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
541 } else if (!(val
& (1 << idx
)) && (opp
->pint
& (1 << idx
))) {
542 DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx
);
543 dst
= &opp
->dst
[idx
];
544 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_RESET
]);
549 case 0x10A0: /* IPI_IPVP */
555 idx
= (addr
- 0x10A0) >> 4;
556 write_IRQreg_ipvp(opp
, opp
->irq_ipi0
+ idx
, val
);
559 case 0x10E0: /* SPVE */
560 opp
->spve
= val
& opp
->vector_mask
;
567 static uint64_t openpic_gbl_read(void *opaque
, hwaddr addr
, unsigned len
)
569 OpenPICState
*opp
= opaque
;
572 DPRINTF("%s: addr " TARGET_FMT_plx
"\n", __func__
, addr
);
577 case 0x1000: /* FREP */
580 case 0x1020: /* GLBC */
583 case 0x1080: /* VENI */
586 case 0x1090: /* PINT */
589 case 0x00: /* Block Revision Register1 (BRR1) */
600 retval
= openpic_cpu_read_internal(opp
, addr
, get_current_cpu());
602 case 0x10A0: /* IPI_IPVP */
608 idx
= (addr
- 0x10A0) >> 4;
609 retval
= read_IRQreg_ipvp(opp
, opp
->irq_ipi0
+ idx
);
612 case 0x10E0: /* SPVE */
618 DPRINTF("%s: => %08x\n", __func__
, retval
);
623 static void openpic_tmr_write(void *opaque
, hwaddr addr
, uint64_t val
,
626 OpenPICState
*opp
= opaque
;
629 DPRINTF("%s: addr %08x <= %08x\n", __func__
, addr
, val
);
632 idx
= (addr
>> 6) & 0x3;
640 switch (addr
& 0x30) {
641 case 0x00: /* TICC (GTCCR) */
643 case 0x10: /* TIBC (GTBCR) */
644 if ((opp
->timers
[idx
].ticc
& TICC_TOG
) != 0 &&
645 (val
& TIBC_CI
) == 0 &&
646 (opp
->timers
[idx
].tibc
& TIBC_CI
) != 0) {
647 opp
->timers
[idx
].ticc
&= ~TICC_TOG
;
649 opp
->timers
[idx
].tibc
= val
;
651 case 0x20: /* TIVP (GTIVPR) */
652 write_IRQreg_ipvp(opp
, opp
->irq_tim0
+ idx
, val
);
654 case 0x30: /* TIDE (GTIDR) */
655 write_IRQreg_ide(opp
, opp
->irq_tim0
+ idx
, val
);
660 static uint64_t openpic_tmr_read(void *opaque
, hwaddr addr
, unsigned len
)
662 OpenPICState
*opp
= opaque
;
663 uint32_t retval
= -1;
666 DPRINTF("%s: addr %08x\n", __func__
, addr
);
670 idx
= (addr
>> 6) & 0x3;
676 switch (addr
& 0x30) {
677 case 0x00: /* TICC (GTCCR) */
678 retval
= opp
->timers
[idx
].ticc
;
680 case 0x10: /* TIBC (GTBCR) */
681 retval
= opp
->timers
[idx
].tibc
;
683 case 0x20: /* TIPV (TIPV) */
684 retval
= read_IRQreg_ipvp(opp
, opp
->irq_tim0
+ idx
);
686 case 0x30: /* TIDE (TIDR) */
687 retval
= read_IRQreg_ide(opp
, opp
->irq_tim0
+ idx
);
692 DPRINTF("%s: => %08x\n", __func__
, retval
);
697 static void openpic_src_write(void *opaque
, hwaddr addr
, uint64_t val
,
700 OpenPICState
*opp
= opaque
;
703 DPRINTF("%s: addr %08x <= %08x\n", __func__
, addr
, val
);
706 addr
= addr
& 0xFFF0;
709 /* EXDE / IFEDE / IEEDE */
710 write_IRQreg_ide(opp
, idx
, val
);
712 /* EXVP / IFEVP / IEEVP */
713 write_IRQreg_ipvp(opp
, idx
, val
);
717 static uint64_t openpic_src_read(void *opaque
, uint64_t addr
, unsigned len
)
719 OpenPICState
*opp
= opaque
;
723 DPRINTF("%s: addr %08x\n", __func__
, addr
);
727 addr
= addr
& 0xFFF0;
730 /* EXDE / IFEDE / IEEDE */
731 retval
= read_IRQreg_ide(opp
, idx
);
733 /* EXVP / IFEVP / IEEVP */
734 retval
= read_IRQreg_ipvp(opp
, idx
);
736 DPRINTF("%s: => %08x\n", __func__
, retval
);
741 static void openpic_msi_write(void *opaque
, hwaddr addr
, uint64_t val
,
744 OpenPICState
*opp
= opaque
;
745 int idx
= opp
->irq_msi
;
748 DPRINTF("%s: addr " TARGET_FMT_plx
" <= %08x\n", __func__
, addr
, val
);
755 srs
= val
>> MSIIR_SRS_SHIFT
;
757 ibs
= (val
& MSIIR_IBS_MASK
) >> MSIIR_IBS_SHIFT
;
758 opp
->msi
[srs
].msir
|= 1 << ibs
;
759 openpic_set_irq(opp
, idx
, 1);
762 /* most registers are read-only, thus ignored */
767 static uint64_t openpic_msi_read(void *opaque
, hwaddr addr
, unsigned size
)
769 OpenPICState
*opp
= opaque
;
773 DPRINTF("%s: addr " TARGET_FMT_plx
"\n", __func__
, addr
);
788 case 0x70: /* MSIRs */
789 r
= opp
->msi
[srs
].msir
;
791 opp
->msi
[srs
].msir
= 0;
793 case 0x120: /* MSISR */
794 for (i
= 0; i
< MAX_MSI
; i
++) {
795 r
|= (opp
->msi
[i
].msir
? 1 : 0) << i
;
803 static void openpic_cpu_write_internal(void *opaque
, hwaddr addr
,
804 uint32_t val
, int idx
)
806 OpenPICState
*opp
= opaque
;
811 DPRINTF("%s: cpu %d addr " TARGET_FMT_plx
" <= %08x\n", __func__
, idx
,
815 dst
= &opp
->dst
[idx
];
818 case 0x40: /* IPIDR */
822 idx
= (addr
- 0x40) >> 4;
823 /* we use IDE as mask which CPUs to deliver the IPI to still. */
824 write_IRQreg_ide(opp
, opp
->irq_ipi0
+ idx
,
825 opp
->src
[opp
->irq_ipi0
+ idx
].ide
| val
);
826 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 1);
827 openpic_set_irq(opp
, opp
->irq_ipi0
+ idx
, 0);
829 case 0x80: /* PCTP */
830 dst
->pctp
= val
& 0x0000000F;
832 case 0x90: /* WHOAMI */
833 /* Read-only register */
835 case 0xA0: /* PIAC */
836 /* Read-only register */
838 case 0xB0: /* PEOI */
840 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
841 IRQ_resetbit(&dst
->servicing
, s_IRQ
);
842 dst
->servicing
.next
= -1;
843 /* Set up next servicing IRQ */
844 s_IRQ
= IRQ_get_next(opp
, &dst
->servicing
);
845 /* Check queued interrupts. */
846 n_IRQ
= IRQ_get_next(opp
, &dst
->raised
);
847 src
= &opp
->src
[n_IRQ
];
850 IPVP_PRIORITY(src
->ipvp
) > dst
->servicing
.priority
)) {
851 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",
853 openpic_irq_raise(opp
, idx
, src
);
861 static void openpic_cpu_write(void *opaque
, hwaddr addr
, uint64_t val
,
864 openpic_cpu_write_internal(opaque
, addr
, val
, (addr
& 0x1f000) >> 12);
867 static uint32_t openpic_cpu_read_internal(void *opaque
, hwaddr addr
,
870 OpenPICState
*opp
= opaque
;
876 DPRINTF("%s: cpu %d addr " TARGET_FMT_plx
"\n", __func__
, idx
, addr
);
880 dst
= &opp
->dst
[idx
];
883 case 0x80: /* PCTP */
886 case 0x90: /* WHOAMI */
889 case 0xA0: /* PIAC */
890 DPRINTF("Lower OpenPIC INT output\n");
891 qemu_irq_lower(dst
->irqs
[OPENPIC_OUTPUT_INT
]);
892 n_IRQ
= IRQ_get_next(opp
, &dst
->raised
);
893 DPRINTF("PIAC: irq=%d\n", n_IRQ
);
895 /* No more interrupt pending */
898 src
= &opp
->src
[n_IRQ
];
899 if (!(src
->ipvp
& IPVP_ACTIVITY_MASK
) ||
900 !(IPVP_PRIORITY(src
->ipvp
) > dst
->pctp
)) {
901 /* - Spurious level-sensitive IRQ
902 * - Priorities has been changed
903 * and the pending IRQ isn't allowed anymore
905 src
->ipvp
&= ~IPVP_ACTIVITY_MASK
;
908 /* IRQ enter servicing state */
909 IRQ_setbit(&dst
->servicing
, n_IRQ
);
910 retval
= IPVP_VECTOR(opp
, src
->ipvp
);
912 IRQ_resetbit(&dst
->raised
, n_IRQ
);
913 dst
->raised
.next
= -1;
914 if (!(src
->ipvp
& IPVP_SENSE_MASK
)) {
915 /* edge-sensitive IRQ */
916 src
->ipvp
&= ~IPVP_ACTIVITY_MASK
;
920 if ((n_IRQ
>= opp
->irq_ipi0
) && (n_IRQ
< (opp
->irq_ipi0
+ MAX_IPI
))) {
921 src
->ide
&= ~(1 << idx
);
922 if (src
->ide
&& !(src
->ipvp
& IPVP_SENSE_MASK
)) {
923 /* trigger on CPUs that didn't know about it yet */
924 openpic_set_irq(opp
, n_IRQ
, 1);
925 openpic_set_irq(opp
, n_IRQ
, 0);
926 /* if all CPUs knew about it, set active bit again */
927 src
->ipvp
|= IPVP_ACTIVITY_MASK
;
932 case 0xB0: /* PEOI */
938 DPRINTF("%s: => %08x\n", __func__
, retval
);
943 static uint64_t openpic_cpu_read(void *opaque
, hwaddr addr
, unsigned len
)
945 return openpic_cpu_read_internal(opaque
, addr
, (addr
& 0x1f000) >> 12);
948 static const MemoryRegionOps openpic_glb_ops_le
= {
949 .write
= openpic_gbl_write
,
950 .read
= openpic_gbl_read
,
951 .endianness
= DEVICE_LITTLE_ENDIAN
,
953 .min_access_size
= 4,
954 .max_access_size
= 4,
958 static const MemoryRegionOps openpic_glb_ops_be
= {
959 .write
= openpic_gbl_write
,
960 .read
= openpic_gbl_read
,
961 .endianness
= DEVICE_BIG_ENDIAN
,
963 .min_access_size
= 4,
964 .max_access_size
= 4,
968 static const MemoryRegionOps openpic_tmr_ops_le
= {
969 .write
= openpic_tmr_write
,
970 .read
= openpic_tmr_read
,
971 .endianness
= DEVICE_LITTLE_ENDIAN
,
973 .min_access_size
= 4,
974 .max_access_size
= 4,
978 static const MemoryRegionOps openpic_tmr_ops_be
= {
979 .write
= openpic_tmr_write
,
980 .read
= openpic_tmr_read
,
981 .endianness
= DEVICE_BIG_ENDIAN
,
983 .min_access_size
= 4,
984 .max_access_size
= 4,
988 static const MemoryRegionOps openpic_cpu_ops_le
= {
989 .write
= openpic_cpu_write
,
990 .read
= openpic_cpu_read
,
991 .endianness
= DEVICE_LITTLE_ENDIAN
,
993 .min_access_size
= 4,
994 .max_access_size
= 4,
998 static const MemoryRegionOps openpic_cpu_ops_be
= {
999 .write
= openpic_cpu_write
,
1000 .read
= openpic_cpu_read
,
1001 .endianness
= DEVICE_BIG_ENDIAN
,
1003 .min_access_size
= 4,
1004 .max_access_size
= 4,
1008 static const MemoryRegionOps openpic_src_ops_le
= {
1009 .write
= openpic_src_write
,
1010 .read
= openpic_src_read
,
1011 .endianness
= DEVICE_LITTLE_ENDIAN
,
1013 .min_access_size
= 4,
1014 .max_access_size
= 4,
1018 static const MemoryRegionOps openpic_src_ops_be
= {
1019 .write
= openpic_src_write
,
1020 .read
= openpic_src_read
,
1021 .endianness
= DEVICE_BIG_ENDIAN
,
1023 .min_access_size
= 4,
1024 .max_access_size
= 4,
1028 static const MemoryRegionOps openpic_msi_ops_le
= {
1029 .read
= openpic_msi_read
,
1030 .write
= openpic_msi_write
,
1031 .endianness
= DEVICE_LITTLE_ENDIAN
,
1033 .min_access_size
= 4,
1034 .max_access_size
= 4,
1038 static const MemoryRegionOps openpic_msi_ops_be
= {
1039 .read
= openpic_msi_read
,
1040 .write
= openpic_msi_write
,
1041 .endianness
= DEVICE_BIG_ENDIAN
,
1043 .min_access_size
= 4,
1044 .max_access_size
= 4,
1048 static void openpic_save_IRQ_queue(QEMUFile
* f
, IRQ_queue_t
*q
)
1052 for (i
= 0; i
< BF_WIDTH(MAX_IRQ
); i
++)
1053 qemu_put_be32s(f
, &q
->queue
[i
]);
1055 qemu_put_sbe32s(f
, &q
->next
);
1056 qemu_put_sbe32s(f
, &q
->priority
);
1059 static void openpic_save(QEMUFile
* f
, void *opaque
)
1061 OpenPICState
*opp
= (OpenPICState
*)opaque
;
1064 qemu_put_be32s(f
, &opp
->glbc
);
1065 qemu_put_be32s(f
, &opp
->veni
);
1066 qemu_put_be32s(f
, &opp
->pint
);
1067 qemu_put_be32s(f
, &opp
->spve
);
1068 qemu_put_be32s(f
, &opp
->tifr
);
1070 for (i
= 0; i
< opp
->max_irq
; i
++) {
1071 qemu_put_be32s(f
, &opp
->src
[i
].ipvp
);
1072 qemu_put_be32s(f
, &opp
->src
[i
].ide
);
1073 qemu_put_sbe32s(f
, &opp
->src
[i
].last_cpu
);
1074 qemu_put_sbe32s(f
, &opp
->src
[i
].pending
);
1077 qemu_put_be32s(f
, &opp
->nb_cpus
);
1079 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1080 qemu_put_be32s(f
, &opp
->dst
[i
].pctp
);
1081 openpic_save_IRQ_queue(f
, &opp
->dst
[i
].raised
);
1082 openpic_save_IRQ_queue(f
, &opp
->dst
[i
].servicing
);
1085 for (i
= 0; i
< MAX_TMR
; i
++) {
1086 qemu_put_be32s(f
, &opp
->timers
[i
].ticc
);
1087 qemu_put_be32s(f
, &opp
->timers
[i
].tibc
);
1091 static void openpic_load_IRQ_queue(QEMUFile
* f
, IRQ_queue_t
*q
)
1095 for (i
= 0; i
< BF_WIDTH(MAX_IRQ
); i
++)
1096 qemu_get_be32s(f
, &q
->queue
[i
]);
1098 qemu_get_sbe32s(f
, &q
->next
);
1099 qemu_get_sbe32s(f
, &q
->priority
);
1102 static int openpic_load(QEMUFile
* f
, void *opaque
, int version_id
)
1104 OpenPICState
*opp
= (OpenPICState
*)opaque
;
1107 if (version_id
!= 1)
1110 qemu_get_be32s(f
, &opp
->glbc
);
1111 qemu_get_be32s(f
, &opp
->veni
);
1112 qemu_get_be32s(f
, &opp
->pint
);
1113 qemu_get_be32s(f
, &opp
->spve
);
1114 qemu_get_be32s(f
, &opp
->tifr
);
1116 for (i
= 0; i
< opp
->max_irq
; i
++) {
1117 qemu_get_be32s(f
, &opp
->src
[i
].ipvp
);
1118 qemu_get_be32s(f
, &opp
->src
[i
].ide
);
1119 qemu_get_sbe32s(f
, &opp
->src
[i
].last_cpu
);
1120 qemu_get_sbe32s(f
, &opp
->src
[i
].pending
);
1123 qemu_get_be32s(f
, &opp
->nb_cpus
);
1125 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1126 qemu_get_be32s(f
, &opp
->dst
[i
].pctp
);
1127 openpic_load_IRQ_queue(f
, &opp
->dst
[i
].raised
);
1128 openpic_load_IRQ_queue(f
, &opp
->dst
[i
].servicing
);
1131 for (i
= 0; i
< MAX_TMR
; i
++) {
1132 qemu_get_be32s(f
, &opp
->timers
[i
].ticc
);
1133 qemu_get_be32s(f
, &opp
->timers
[i
].tibc
);
1139 static void openpic_irq_raise(OpenPICState
*opp
, int n_CPU
, IRQ_src_t
*src
)
1141 int n_ci
= IDR_CI0_SHIFT
- n_CPU
;
1143 if ((opp
->flags
& OPENPIC_FLAG_IDE_CRIT
) && (src
->ide
& (1 << n_ci
))) {
1144 qemu_irq_raise(opp
->dst
[n_CPU
].irqs
[OPENPIC_OUTPUT_CINT
]);
1146 qemu_irq_raise(opp
->dst
[n_CPU
].irqs
[OPENPIC_OUTPUT_INT
]);
1152 MemoryRegionOps
const *ops
;
1158 static int openpic_init(SysBusDevice
*dev
)
1160 OpenPICState
*opp
= FROM_SYSBUS(typeof (*opp
), dev
);
1162 struct memreg list_le
[] = {
1163 {"glb", &openpic_glb_ops_le
, true,
1164 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1165 {"tmr", &openpic_tmr_ops_le
, true,
1166 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1167 {"msi", &openpic_msi_ops_le
, true,
1168 OPENPIC_MSI_REG_START
, OPENPIC_MSI_REG_SIZE
},
1169 {"src", &openpic_src_ops_le
, true,
1170 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1171 {"cpu", &openpic_cpu_ops_le
, true,
1172 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1174 struct memreg list_be
[] = {
1175 {"glb", &openpic_glb_ops_be
, true,
1176 OPENPIC_GLB_REG_START
, OPENPIC_GLB_REG_SIZE
},
1177 {"tmr", &openpic_tmr_ops_be
, true,
1178 OPENPIC_TMR_REG_START
, OPENPIC_TMR_REG_SIZE
},
1179 {"msi", &openpic_msi_ops_be
, true,
1180 OPENPIC_MSI_REG_START
, OPENPIC_MSI_REG_SIZE
},
1181 {"src", &openpic_src_ops_be
, true,
1182 OPENPIC_SRC_REG_START
, OPENPIC_SRC_REG_SIZE
},
1183 {"cpu", &openpic_cpu_ops_be
, true,
1184 OPENPIC_CPU_REG_START
, OPENPIC_CPU_REG_SIZE
},
1186 struct memreg
*list
;
1188 switch (opp
->model
) {
1189 case OPENPIC_MODEL_FSL_MPIC_20
:
1191 opp
->flags
|= OPENPIC_FLAG_IDE_CRIT
;
1193 opp
->vid
= VID_REVISION_1_2
;
1194 opp
->veni
= VENI_GENERIC
;
1195 opp
->vector_mask
= 0xFFFF;
1196 opp
->tifr_reset
= 0;
1197 opp
->ipvp_reset
= IPVP_MASK_MASK
;
1198 opp
->ide_reset
= 1 << 0;
1199 opp
->max_irq
= FSL_MPIC_20_MAX_IRQ
;
1200 opp
->irq_ipi0
= FSL_MPIC_20_IPI_IRQ
;
1201 opp
->irq_tim0
= FSL_MPIC_20_TMR_IRQ
;
1202 opp
->irq_msi
= FSL_MPIC_20_MSI_IRQ
;
1203 opp
->brr1
= FSL_BRR1_IPID
| FSL_BRR1_IPMJ
| FSL_BRR1_IPMN
;
1204 msi_supported
= true;
1207 case OPENPIC_MODEL_RAVEN
:
1208 opp
->nb_irqs
= RAVEN_MAX_EXT
;
1209 opp
->vid
= VID_REVISION_1_3
;
1210 opp
->veni
= VENI_GENERIC
;
1211 opp
->vector_mask
= 0xFF;
1212 opp
->tifr_reset
= 4160000;
1213 opp
->ipvp_reset
= IPVP_MASK_MASK
| IPVP_MODE_MASK
;
1215 opp
->max_irq
= RAVEN_MAX_IRQ
;
1216 opp
->irq_ipi0
= RAVEN_IPI_IRQ
;
1217 opp
->irq_tim0
= RAVEN_TMR_IRQ
;
1220 /* Don't map MSI region */
1221 list
[2].map
= false;
1223 /* Only UP supported today */
1224 if (opp
->nb_cpus
!= 1) {
1230 memory_region_init(&opp
->mem
, "openpic", 0x40000);
1232 for (i
= 0; i
< ARRAY_SIZE(list_le
); i
++) {
1237 memory_region_init_io(&opp
->sub_io_mem
[i
], list
[i
].ops
, opp
,
1238 list
[i
].name
, list
[i
].size
);
1240 memory_region_add_subregion(&opp
->mem
, list
[i
].start_addr
,
1241 &opp
->sub_io_mem
[i
]);
1244 for (i
= 0; i
< opp
->nb_cpus
; i
++) {
1245 opp
->dst
[i
].irqs
= g_new(qemu_irq
, OPENPIC_OUTPUT_NB
);
1246 for (j
= 0; j
< OPENPIC_OUTPUT_NB
; j
++) {
1247 sysbus_init_irq(dev
, &opp
->dst
[i
].irqs
[j
]);
1251 register_savevm(&opp
->busdev
.qdev
, "openpic", 0, 2,
1252 openpic_save
, openpic_load
, opp
);
1254 sysbus_init_mmio(dev
, &opp
->mem
);
1255 qdev_init_gpio_in(&dev
->qdev
, openpic_set_irq
, opp
->max_irq
);
1260 static Property openpic_properties
[] = {
1261 DEFINE_PROP_UINT32("model", OpenPICState
, model
, OPENPIC_MODEL_FSL_MPIC_20
),
1262 DEFINE_PROP_UINT32("nb_cpus", OpenPICState
, nb_cpus
, 1),
1263 DEFINE_PROP_END_OF_LIST(),
1266 static void openpic_class_init(ObjectClass
*klass
, void *data
)
1268 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1269 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
1271 k
->init
= openpic_init
;
1272 dc
->props
= openpic_properties
;
1273 dc
->reset
= openpic_reset
;
1276 static TypeInfo openpic_info
= {
1278 .parent
= TYPE_SYS_BUS_DEVICE
,
1279 .instance_size
= sizeof(OpenPICState
),
1280 .class_init
= openpic_class_init
,
1283 static void openpic_register_types(void)
1285 type_register_static(&openpic_info
);
1288 type_init(openpic_register_types
)