2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 #include "qemu/osdep.h"
29 #include "qapi/error.h"
30 #include "qemu-common.h"
34 #include "qemu/timer.h"
35 #include "hw/ppc/xics.h"
36 #include "qemu/error-report.h"
37 #include "qapi/visitor.h"
38 #include "monitor/monitor.h"
39 #include "hw/intc/intc.h"
41 void xics_cpu_destroy(XICSFabric
*xi
, PowerPCCPU
*cpu
)
43 CPUState
*cs
= CPU(cpu
);
44 ICPState
*icp
= ICP(cpu
->intc
);
47 assert(cs
== icp
->cs
);
53 void xics_cpu_setup(XICSFabric
*xi
, PowerPCCPU
*cpu
, ICPState
*icp
)
55 CPUState
*cs
= CPU(cpu
);
56 CPUPPCState
*env
= &cpu
->env
;
61 cpu
->intc
= OBJECT(icp
);
64 icpc
= ICP_GET_CLASS(icp
);
65 if (icpc
->cpu_setup
) {
66 icpc
->cpu_setup(icp
, cpu
);
69 switch (PPC_INPUT(env
)) {
70 case PPC_FLAGS_INPUT_POWER7
:
71 icp
->output
= env
->irq_inputs
[POWER7_INPUT_INT
];
74 case PPC_FLAGS_INPUT_970
:
75 icp
->output
= env
->irq_inputs
[PPC970_INPUT_INT
];
79 error_report("XICS interrupt controller does not support this CPU "
85 void icp_pic_print_info(ICPState
*icp
, Monitor
*mon
)
87 int cpu_index
= icp
->cs
? icp
->cs
->cpu_index
: -1;
92 monitor_printf(mon
, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
93 cpu_index
, icp
->xirr
, icp
->xirr_owner
,
94 icp
->pending_priority
, icp
->mfrr
);
97 void ics_pic_print_info(ICSState
*ics
, Monitor
*mon
)
101 monitor_printf(mon
, "ICS %4x..%4x %p\n",
102 ics
->offset
, ics
->offset
+ ics
->nr_irqs
- 1, ics
);
108 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
109 ICSIRQState
*irq
= ics
->irqs
+ i
;
111 if (!(irq
->flags
& XICS_FLAGS_IRQ_MASK
)) {
114 monitor_printf(mon
, " %4x %s %02x %02x\n",
116 (irq
->flags
& XICS_FLAGS_IRQ_LSI
) ?
118 irq
->priority
, irq
->status
);
123 * ICP: Presentation layer
126 #define XISR_MASK 0x00ffffff
127 #define CPPR_MASK 0xff000000
129 #define XISR(icp) (((icp)->xirr) & XISR_MASK)
130 #define CPPR(icp) (((icp)->xirr) >> 24)
132 static void ics_reject(ICSState
*ics
, uint32_t nr
)
134 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
141 void ics_resend(ICSState
*ics
)
143 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
150 static void ics_eoi(ICSState
*ics
, int nr
)
152 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
159 static void icp_check_ipi(ICPState
*icp
)
161 if (XISR(icp
) && (icp
->pending_priority
<= icp
->mfrr
)) {
165 trace_xics_icp_check_ipi(icp
->cs
->cpu_index
, icp
->mfrr
);
167 if (XISR(icp
) && icp
->xirr_owner
) {
168 ics_reject(icp
->xirr_owner
, XISR(icp
));
171 icp
->xirr
= (icp
->xirr
& ~XISR_MASK
) | XICS_IPI
;
172 icp
->pending_priority
= icp
->mfrr
;
173 icp
->xirr_owner
= NULL
;
174 qemu_irq_raise(icp
->output
);
177 void icp_resend(ICPState
*icp
)
179 XICSFabric
*xi
= icp
->xics
;
180 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
182 if (icp
->mfrr
< CPPR(icp
)) {
189 void icp_set_cppr(ICPState
*icp
, uint8_t cppr
)
194 old_cppr
= CPPR(icp
);
195 icp
->xirr
= (icp
->xirr
& ~CPPR_MASK
) | (cppr
<< 24);
197 if (cppr
< old_cppr
) {
198 if (XISR(icp
) && (cppr
<= icp
->pending_priority
)) {
199 old_xisr
= XISR(icp
);
200 icp
->xirr
&= ~XISR_MASK
; /* Clear XISR */
201 icp
->pending_priority
= 0xff;
202 qemu_irq_lower(icp
->output
);
203 if (icp
->xirr_owner
) {
204 ics_reject(icp
->xirr_owner
, old_xisr
);
205 icp
->xirr_owner
= NULL
;
215 void icp_set_mfrr(ICPState
*icp
, uint8_t mfrr
)
218 if (mfrr
< CPPR(icp
)) {
223 uint32_t icp_accept(ICPState
*icp
)
225 uint32_t xirr
= icp
->xirr
;
227 qemu_irq_lower(icp
->output
);
228 icp
->xirr
= icp
->pending_priority
<< 24;
229 icp
->pending_priority
= 0xff;
230 icp
->xirr_owner
= NULL
;
232 trace_xics_icp_accept(xirr
, icp
->xirr
);
237 uint32_t icp_ipoll(ICPState
*icp
, uint32_t *mfrr
)
245 void icp_eoi(ICPState
*icp
, uint32_t xirr
)
247 XICSFabric
*xi
= icp
->xics
;
248 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
252 /* Send EOI -> ICS */
253 icp
->xirr
= (icp
->xirr
& ~CPPR_MASK
) | (xirr
& CPPR_MASK
);
254 trace_xics_icp_eoi(icp
->cs
->cpu_index
, xirr
, icp
->xirr
);
255 irq
= xirr
& XISR_MASK
;
257 ics
= xic
->ics_get(xi
, irq
);
266 static void icp_irq(ICSState
*ics
, int server
, int nr
, uint8_t priority
)
268 ICPState
*icp
= xics_icp_get(ics
->xics
, server
);
270 trace_xics_icp_irq(server
, nr
, priority
);
272 if ((priority
>= CPPR(icp
))
273 || (XISR(icp
) && (icp
->pending_priority
<= priority
))) {
276 if (XISR(icp
) && icp
->xirr_owner
) {
277 ics_reject(icp
->xirr_owner
, XISR(icp
));
278 icp
->xirr_owner
= NULL
;
280 icp
->xirr
= (icp
->xirr
& ~XISR_MASK
) | (nr
& XISR_MASK
);
281 icp
->xirr_owner
= ics
;
282 icp
->pending_priority
= priority
;
283 trace_xics_icp_raise(icp
->xirr
, icp
->pending_priority
);
284 qemu_irq_raise(icp
->output
);
288 static void icp_dispatch_pre_save(void *opaque
)
290 ICPState
*icp
= opaque
;
291 ICPStateClass
*info
= ICP_GET_CLASS(icp
);
293 if (info
->pre_save
) {
298 static int icp_dispatch_post_load(void *opaque
, int version_id
)
300 ICPState
*icp
= opaque
;
301 ICPStateClass
*info
= ICP_GET_CLASS(icp
);
303 if (info
->post_load
) {
304 return info
->post_load(icp
, version_id
);
310 static const VMStateDescription vmstate_icp_server
= {
311 .name
= "icp/server",
313 .minimum_version_id
= 1,
314 .pre_save
= icp_dispatch_pre_save
,
315 .post_load
= icp_dispatch_post_load
,
316 .fields
= (VMStateField
[]) {
318 VMSTATE_UINT32(xirr
, ICPState
),
319 VMSTATE_UINT8(pending_priority
, ICPState
),
320 VMSTATE_UINT8(mfrr
, ICPState
),
321 VMSTATE_END_OF_LIST()
325 static void icp_reset(void *dev
)
327 ICPState
*icp
= ICP(dev
);
328 ICPStateClass
*icpc
= ICP_GET_CLASS(icp
);
331 icp
->pending_priority
= 0xff;
334 /* Make all outputs are deasserted */
335 qemu_set_irq(icp
->output
, 0);
342 static void icp_realize(DeviceState
*dev
, Error
**errp
)
344 ICPState
*icp
= ICP(dev
);
345 ICPStateClass
*icpc
= ICP_GET_CLASS(dev
);
349 obj
= object_property_get_link(OBJECT(dev
), ICP_PROP_XICS
, &err
);
351 error_setg(errp
, "%s: required link '" ICP_PROP_XICS
"' not found: %s",
352 __func__
, error_get_pretty(err
));
356 icp
->xics
= XICS_FABRIC(obj
);
359 icpc
->realize(dev
, errp
);
362 qemu_register_reset(icp_reset
, dev
);
365 static void icp_unrealize(DeviceState
*dev
, Error
**errp
)
367 qemu_unregister_reset(icp_reset
, dev
);
370 static void icp_class_init(ObjectClass
*klass
, void *data
)
372 DeviceClass
*dc
= DEVICE_CLASS(klass
);
374 dc
->vmsd
= &vmstate_icp_server
;
375 dc
->realize
= icp_realize
;
376 dc
->unrealize
= icp_unrealize
;
379 static const TypeInfo icp_info
= {
381 .parent
= TYPE_DEVICE
,
382 .instance_size
= sizeof(ICPState
),
383 .class_init
= icp_class_init
,
384 .class_size
= sizeof(ICPStateClass
),
390 static void ics_simple_resend_msi(ICSState
*ics
, int srcno
)
392 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
394 /* FIXME: filter by server#? */
395 if (irq
->status
& XICS_STATUS_REJECTED
) {
396 irq
->status
&= ~XICS_STATUS_REJECTED
;
397 if (irq
->priority
!= 0xff) {
398 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
403 static void ics_simple_resend_lsi(ICSState
*ics
, int srcno
)
405 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
407 if ((irq
->priority
!= 0xff)
408 && (irq
->status
& XICS_STATUS_ASSERTED
)
409 && !(irq
->status
& XICS_STATUS_SENT
)) {
410 irq
->status
|= XICS_STATUS_SENT
;
411 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
415 static void ics_simple_set_irq_msi(ICSState
*ics
, int srcno
, int val
)
417 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
419 trace_xics_ics_simple_set_irq_msi(srcno
, srcno
+ ics
->offset
);
422 if (irq
->priority
== 0xff) {
423 irq
->status
|= XICS_STATUS_MASKED_PENDING
;
424 trace_xics_masked_pending();
426 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
431 static void ics_simple_set_irq_lsi(ICSState
*ics
, int srcno
, int val
)
433 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
435 trace_xics_ics_simple_set_irq_lsi(srcno
, srcno
+ ics
->offset
);
437 irq
->status
|= XICS_STATUS_ASSERTED
;
439 irq
->status
&= ~XICS_STATUS_ASSERTED
;
441 ics_simple_resend_lsi(ics
, srcno
);
444 static void ics_simple_set_irq(void *opaque
, int srcno
, int val
)
446 ICSState
*ics
= (ICSState
*)opaque
;
448 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
449 ics_simple_set_irq_lsi(ics
, srcno
, val
);
451 ics_simple_set_irq_msi(ics
, srcno
, val
);
455 static void ics_simple_write_xive_msi(ICSState
*ics
, int srcno
)
457 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
459 if (!(irq
->status
& XICS_STATUS_MASKED_PENDING
)
460 || (irq
->priority
== 0xff)) {
464 irq
->status
&= ~XICS_STATUS_MASKED_PENDING
;
465 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
468 static void ics_simple_write_xive_lsi(ICSState
*ics
, int srcno
)
470 ics_simple_resend_lsi(ics
, srcno
);
473 void ics_simple_write_xive(ICSState
*ics
, int srcno
, int server
,
474 uint8_t priority
, uint8_t saved_priority
)
476 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
478 irq
->server
= server
;
479 irq
->priority
= priority
;
480 irq
->saved_priority
= saved_priority
;
482 trace_xics_ics_simple_write_xive(ics
->offset
+ srcno
, srcno
, server
,
485 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
486 ics_simple_write_xive_lsi(ics
, srcno
);
488 ics_simple_write_xive_msi(ics
, srcno
);
492 static void ics_simple_reject(ICSState
*ics
, uint32_t nr
)
494 ICSIRQState
*irq
= ics
->irqs
+ nr
- ics
->offset
;
496 trace_xics_ics_simple_reject(nr
, nr
- ics
->offset
);
497 if (irq
->flags
& XICS_FLAGS_IRQ_MSI
) {
498 irq
->status
|= XICS_STATUS_REJECTED
;
499 } else if (irq
->flags
& XICS_FLAGS_IRQ_LSI
) {
500 irq
->status
&= ~XICS_STATUS_SENT
;
504 static void ics_simple_resend(ICSState
*ics
)
508 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
509 /* FIXME: filter by server#? */
510 if (ics
->irqs
[i
].flags
& XICS_FLAGS_IRQ_LSI
) {
511 ics_simple_resend_lsi(ics
, i
);
513 ics_simple_resend_msi(ics
, i
);
518 static void ics_simple_eoi(ICSState
*ics
, uint32_t nr
)
520 int srcno
= nr
- ics
->offset
;
521 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
523 trace_xics_ics_simple_eoi(nr
);
525 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
526 irq
->status
&= ~XICS_STATUS_SENT
;
530 static void ics_simple_reset(void *dev
)
532 ICSState
*ics
= ICS_SIMPLE(dev
);
534 uint8_t flags
[ics
->nr_irqs
];
536 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
537 flags
[i
] = ics
->irqs
[i
].flags
;
540 memset(ics
->irqs
, 0, sizeof(ICSIRQState
) * ics
->nr_irqs
);
542 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
543 ics
->irqs
[i
].priority
= 0xff;
544 ics
->irqs
[i
].saved_priority
= 0xff;
545 ics
->irqs
[i
].flags
= flags
[i
];
549 static void ics_simple_dispatch_pre_save(void *opaque
)
551 ICSState
*ics
= opaque
;
552 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
554 if (info
->pre_save
) {
559 static int ics_simple_dispatch_post_load(void *opaque
, int version_id
)
561 ICSState
*ics
= opaque
;
562 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
564 if (info
->post_load
) {
565 return info
->post_load(ics
, version_id
);
571 static const VMStateDescription vmstate_ics_simple_irq
= {
574 .minimum_version_id
= 1,
575 .fields
= (VMStateField
[]) {
576 VMSTATE_UINT32(server
, ICSIRQState
),
577 VMSTATE_UINT8(priority
, ICSIRQState
),
578 VMSTATE_UINT8(saved_priority
, ICSIRQState
),
579 VMSTATE_UINT8(status
, ICSIRQState
),
580 VMSTATE_UINT8(flags
, ICSIRQState
),
581 VMSTATE_END_OF_LIST()
585 static const VMStateDescription vmstate_ics_simple
= {
588 .minimum_version_id
= 1,
589 .pre_save
= ics_simple_dispatch_pre_save
,
590 .post_load
= ics_simple_dispatch_post_load
,
591 .fields
= (VMStateField
[]) {
593 VMSTATE_UINT32_EQUAL(nr_irqs
, ICSState
),
595 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs
, ICSState
, nr_irqs
,
596 vmstate_ics_simple_irq
,
598 VMSTATE_END_OF_LIST()
602 static void ics_simple_initfn(Object
*obj
)
604 ICSState
*ics
= ICS_SIMPLE(obj
);
606 ics
->offset
= XICS_IRQ_BASE
;
609 static void ics_simple_realize(DeviceState
*dev
, Error
**errp
)
611 ICSState
*ics
= ICS_SIMPLE(dev
);
614 error_setg(errp
, "Number of interrupts needs to be greater 0");
617 ics
->irqs
= g_malloc0(ics
->nr_irqs
* sizeof(ICSIRQState
));
618 ics
->qirqs
= qemu_allocate_irqs(ics_simple_set_irq
, ics
, ics
->nr_irqs
);
620 qemu_register_reset(ics_simple_reset
, dev
);
623 static Property ics_simple_properties
[] = {
624 DEFINE_PROP_UINT32("nr-irqs", ICSState
, nr_irqs
, 0),
625 DEFINE_PROP_END_OF_LIST(),
628 static void ics_simple_class_init(ObjectClass
*klass
, void *data
)
630 DeviceClass
*dc
= DEVICE_CLASS(klass
);
631 ICSStateClass
*isc
= ICS_BASE_CLASS(klass
);
633 isc
->realize
= ics_simple_realize
;
634 dc
->props
= ics_simple_properties
;
635 dc
->vmsd
= &vmstate_ics_simple
;
636 isc
->reject
= ics_simple_reject
;
637 isc
->resend
= ics_simple_resend
;
638 isc
->eoi
= ics_simple_eoi
;
641 static const TypeInfo ics_simple_info
= {
642 .name
= TYPE_ICS_SIMPLE
,
643 .parent
= TYPE_ICS_BASE
,
644 .instance_size
= sizeof(ICSState
),
645 .class_init
= ics_simple_class_init
,
646 .class_size
= sizeof(ICSStateClass
),
647 .instance_init
= ics_simple_initfn
,
650 static void ics_base_realize(DeviceState
*dev
, Error
**errp
)
652 ICSStateClass
*icsc
= ICS_BASE_GET_CLASS(dev
);
653 ICSState
*ics
= ICS_BASE(dev
);
657 obj
= object_property_get_link(OBJECT(dev
), ICS_PROP_XICS
, &err
);
659 error_setg(errp
, "%s: required link '" ICS_PROP_XICS
"' not found: %s",
660 __func__
, error_get_pretty(err
));
663 ics
->xics
= XICS_FABRIC(obj
);
667 icsc
->realize(dev
, errp
);
671 static void ics_base_class_init(ObjectClass
*klass
, void *data
)
673 DeviceClass
*dc
= DEVICE_CLASS(klass
);
675 dc
->realize
= ics_base_realize
;
678 static const TypeInfo ics_base_info
= {
679 .name
= TYPE_ICS_BASE
,
680 .parent
= TYPE_DEVICE
,
682 .instance_size
= sizeof(ICSState
),
683 .class_init
= ics_base_class_init
,
684 .class_size
= sizeof(ICSStateClass
),
687 static const TypeInfo xics_fabric_info
= {
688 .name
= TYPE_XICS_FABRIC
,
689 .parent
= TYPE_INTERFACE
,
690 .class_size
= sizeof(XICSFabricClass
),
696 qemu_irq
xics_get_qirq(XICSFabric
*xi
, int irq
)
698 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
699 ICSState
*ics
= xic
->ics_get(xi
, irq
);
702 return ics
->qirqs
[irq
- ics
->offset
];
708 ICPState
*xics_icp_get(XICSFabric
*xi
, int server
)
710 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
712 return xic
->icp_get(xi
, server
);
715 void ics_set_irq_type(ICSState
*ics
, int srcno
, bool lsi
)
717 assert(!(ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_MASK
));
719 ics
->irqs
[srcno
].flags
|=
720 lsi
? XICS_FLAGS_IRQ_LSI
: XICS_FLAGS_IRQ_MSI
;
723 static void xics_register_types(void)
725 type_register_static(&ics_simple_info
);
726 type_register_static(&ics_base_info
);
727 type_register_static(&icp_info
);
728 type_register_static(&xics_fabric_info
);
731 type_init(xics_register_types
)