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"
32 #include "qemu/timer.h"
33 #include "hw/ppc/xics.h"
34 #include "hw/qdev-properties.h"
35 #include "qemu/error-report.h"
36 #include "qemu/module.h"
37 #include "qapi/visitor.h"
38 #include "migration/vmstate.h"
39 #include "monitor/monitor.h"
40 #include "hw/intc/intc.h"
42 #include "sysemu/kvm.h"
43 #include "sysemu/reset.h"
45 void icp_pic_print_info(ICPState
*icp
, Monitor
*mon
)
47 int cpu_index
= icp
->cs
? icp
->cs
->cpu_index
: -1;
53 if (kvm_irqchip_in_kernel()) {
54 icp_synchronize_state(icp
);
57 monitor_printf(mon
, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
58 cpu_index
, icp
->xirr
, icp
->xirr_owner
,
59 icp
->pending_priority
, icp
->mfrr
);
62 void ics_pic_print_info(ICSState
*ics
, Monitor
*mon
)
66 monitor_printf(mon
, "ICS %4x..%4x %p\n",
67 ics
->offset
, ics
->offset
+ ics
->nr_irqs
- 1, ics
);
73 if (kvm_irqchip_in_kernel()) {
74 ics_synchronize_state(ics
);
77 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
78 ICSIRQState
*irq
= ics
->irqs
+ i
;
80 if (!(irq
->flags
& XICS_FLAGS_IRQ_MASK
)) {
83 monitor_printf(mon
, " %4x %s %02x %02x\n",
85 (irq
->flags
& XICS_FLAGS_IRQ_LSI
) ?
87 irq
->priority
, irq
->status
);
92 * ICP: Presentation layer
95 #define XISR_MASK 0x00ffffff
96 #define CPPR_MASK 0xff000000
98 #define XISR(icp) (((icp)->xirr) & XISR_MASK)
99 #define CPPR(icp) (((icp)->xirr) >> 24)
101 static void ics_reject(ICSState
*ics
, uint32_t nr
);
102 static void ics_eoi(ICSState
*ics
, uint32_t nr
);
104 static void icp_check_ipi(ICPState
*icp
)
106 if (XISR(icp
) && (icp
->pending_priority
<= icp
->mfrr
)) {
110 trace_xics_icp_check_ipi(icp
->cs
->cpu_index
, icp
->mfrr
);
112 if (XISR(icp
) && icp
->xirr_owner
) {
113 ics_reject(icp
->xirr_owner
, XISR(icp
));
116 icp
->xirr
= (icp
->xirr
& ~XISR_MASK
) | XICS_IPI
;
117 icp
->pending_priority
= icp
->mfrr
;
118 icp
->xirr_owner
= NULL
;
119 qemu_irq_raise(icp
->output
);
122 void icp_resend(ICPState
*icp
)
124 XICSFabric
*xi
= icp
->xics
;
125 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
127 if (icp
->mfrr
< CPPR(icp
)) {
134 void icp_set_cppr(ICPState
*icp
, uint8_t cppr
)
139 old_cppr
= CPPR(icp
);
140 icp
->xirr
= (icp
->xirr
& ~CPPR_MASK
) | (cppr
<< 24);
142 if (cppr
< old_cppr
) {
143 if (XISR(icp
) && (cppr
<= icp
->pending_priority
)) {
144 old_xisr
= XISR(icp
);
145 icp
->xirr
&= ~XISR_MASK
; /* Clear XISR */
146 icp
->pending_priority
= 0xff;
147 qemu_irq_lower(icp
->output
);
148 if (icp
->xirr_owner
) {
149 ics_reject(icp
->xirr_owner
, old_xisr
);
150 icp
->xirr_owner
= NULL
;
160 void icp_set_mfrr(ICPState
*icp
, uint8_t mfrr
)
163 if (mfrr
< CPPR(icp
)) {
168 uint32_t icp_accept(ICPState
*icp
)
170 uint32_t xirr
= icp
->xirr
;
172 qemu_irq_lower(icp
->output
);
173 icp
->xirr
= icp
->pending_priority
<< 24;
174 icp
->pending_priority
= 0xff;
175 icp
->xirr_owner
= NULL
;
177 trace_xics_icp_accept(xirr
, icp
->xirr
);
182 uint32_t icp_ipoll(ICPState
*icp
, uint32_t *mfrr
)
190 void icp_eoi(ICPState
*icp
, uint32_t xirr
)
192 XICSFabric
*xi
= icp
->xics
;
193 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
197 /* Send EOI -> ICS */
198 icp
->xirr
= (icp
->xirr
& ~CPPR_MASK
) | (xirr
& CPPR_MASK
);
199 trace_xics_icp_eoi(icp
->cs
->cpu_index
, xirr
, icp
->xirr
);
200 irq
= xirr
& XISR_MASK
;
202 ics
= xic
->ics_get(xi
, irq
);
211 static void icp_irq(ICSState
*ics
, int server
, int nr
, uint8_t priority
)
213 ICPState
*icp
= xics_icp_get(ics
->xics
, server
);
215 trace_xics_icp_irq(server
, nr
, priority
);
217 if ((priority
>= CPPR(icp
))
218 || (XISR(icp
) && (icp
->pending_priority
<= priority
))) {
221 if (XISR(icp
) && icp
->xirr_owner
) {
222 ics_reject(icp
->xirr_owner
, XISR(icp
));
223 icp
->xirr_owner
= NULL
;
225 icp
->xirr
= (icp
->xirr
& ~XISR_MASK
) | (nr
& XISR_MASK
);
226 icp
->xirr_owner
= ics
;
227 icp
->pending_priority
= priority
;
228 trace_xics_icp_raise(icp
->xirr
, icp
->pending_priority
);
229 qemu_irq_raise(icp
->output
);
233 static int icp_pre_save(void *opaque
)
235 ICPState
*icp
= opaque
;
237 if (kvm_irqchip_in_kernel()) {
238 icp_get_kvm_state(icp
);
244 static int icp_post_load(void *opaque
, int version_id
)
246 ICPState
*icp
= opaque
;
248 if (kvm_irqchip_in_kernel()) {
249 Error
*local_err
= NULL
;
252 ret
= icp_set_kvm_state(icp
, &local_err
);
254 error_report_err(local_err
);
262 static const VMStateDescription vmstate_icp_server
= {
263 .name
= "icp/server",
265 .minimum_version_id
= 1,
266 .pre_save
= icp_pre_save
,
267 .post_load
= icp_post_load
,
268 .fields
= (VMStateField
[]) {
270 VMSTATE_UINT32(xirr
, ICPState
),
271 VMSTATE_UINT8(pending_priority
, ICPState
),
272 VMSTATE_UINT8(mfrr
, ICPState
),
273 VMSTATE_END_OF_LIST()
277 void icp_reset(ICPState
*icp
)
280 icp
->pending_priority
= 0xff;
283 /* Make all outputs are deasserted */
284 qemu_set_irq(icp
->output
, 0);
286 if (kvm_irqchip_in_kernel()) {
287 Error
*local_err
= NULL
;
289 icp_set_kvm_state(icp
, &local_err
);
291 error_report_err(local_err
);
296 static void icp_realize(DeviceState
*dev
, Error
**errp
)
298 ICPState
*icp
= ICP(dev
);
304 obj
= object_property_get_link(OBJECT(dev
), ICP_PROP_XICS
, &err
);
306 error_propagate_prepend(errp
, err
,
307 "required link '" ICP_PROP_XICS
312 icp
->xics
= XICS_FABRIC(obj
);
314 obj
= object_property_get_link(OBJECT(dev
), ICP_PROP_CPU
, &err
);
316 error_propagate_prepend(errp
, err
,
317 "required link '" ICP_PROP_CPU
322 cpu
= POWERPC_CPU(obj
);
326 switch (PPC_INPUT(env
)) {
327 case PPC_FLAGS_INPUT_POWER7
:
328 icp
->output
= env
->irq_inputs
[POWER7_INPUT_INT
];
330 case PPC_FLAGS_INPUT_POWER9
: /* For SPAPR xics emulation */
331 icp
->output
= env
->irq_inputs
[POWER9_INPUT_INT
];
334 case PPC_FLAGS_INPUT_970
:
335 icp
->output
= env
->irq_inputs
[PPC970_INPUT_INT
];
339 error_setg(errp
, "XICS interrupt controller does not support this CPU bus model");
343 /* Connect the presenter to the VCPU (required for CPU hotplug) */
344 if (kvm_irqchip_in_kernel()) {
345 icp_kvm_realize(dev
, &err
);
347 error_propagate(errp
, err
);
352 vmstate_register(NULL
, icp
->cs
->cpu_index
, &vmstate_icp_server
, icp
);
355 static void icp_unrealize(DeviceState
*dev
, Error
**errp
)
357 ICPState
*icp
= ICP(dev
);
359 vmstate_unregister(NULL
, &vmstate_icp_server
, icp
);
362 static void icp_class_init(ObjectClass
*klass
, void *data
)
364 DeviceClass
*dc
= DEVICE_CLASS(klass
);
366 dc
->realize
= icp_realize
;
367 dc
->unrealize
= icp_unrealize
;
369 * Reason: part of XICS interrupt controller, needs to be wired up
372 dc
->user_creatable
= false;
375 static const TypeInfo icp_info
= {
377 .parent
= TYPE_DEVICE
,
378 .instance_size
= sizeof(ICPState
),
379 .class_init
= icp_class_init
,
380 .class_size
= sizeof(ICPStateClass
),
383 Object
*icp_create(Object
*cpu
, const char *type
, XICSFabric
*xi
, Error
**errp
)
385 Error
*local_err
= NULL
;
388 obj
= object_new(type
);
389 object_property_add_child(cpu
, type
, obj
, &error_abort
);
391 object_property_add_const_link(obj
, ICP_PROP_XICS
, OBJECT(xi
),
393 object_property_add_const_link(obj
, ICP_PROP_CPU
, cpu
, &error_abort
);
394 object_property_set_bool(obj
, true, "realized", &local_err
);
396 object_unparent(obj
);
397 error_propagate(errp
, local_err
);
407 static void ics_resend_msi(ICSState
*ics
, int srcno
)
409 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
411 /* FIXME: filter by server#? */
412 if (irq
->status
& XICS_STATUS_REJECTED
) {
413 irq
->status
&= ~XICS_STATUS_REJECTED
;
414 if (irq
->priority
!= 0xff) {
415 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
420 static void ics_resend_lsi(ICSState
*ics
, int srcno
)
422 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
424 if ((irq
->priority
!= 0xff)
425 && (irq
->status
& XICS_STATUS_ASSERTED
)
426 && !(irq
->status
& XICS_STATUS_SENT
)) {
427 irq
->status
|= XICS_STATUS_SENT
;
428 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
432 static void ics_set_irq_msi(ICSState
*ics
, int srcno
, int val
)
434 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
436 trace_xics_ics_set_irq_msi(srcno
, srcno
+ ics
->offset
);
439 if (irq
->priority
== 0xff) {
440 irq
->status
|= XICS_STATUS_MASKED_PENDING
;
441 trace_xics_masked_pending();
443 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
448 static void ics_set_irq_lsi(ICSState
*ics
, int srcno
, int val
)
450 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
452 trace_xics_ics_set_irq_lsi(srcno
, srcno
+ ics
->offset
);
454 irq
->status
|= XICS_STATUS_ASSERTED
;
456 irq
->status
&= ~XICS_STATUS_ASSERTED
;
458 ics_resend_lsi(ics
, srcno
);
461 void ics_set_irq(void *opaque
, int srcno
, int val
)
463 ICSState
*ics
= (ICSState
*)opaque
;
465 if (kvm_irqchip_in_kernel()) {
466 ics_kvm_set_irq(ics
, srcno
, val
);
470 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
471 ics_set_irq_lsi(ics
, srcno
, val
);
473 ics_set_irq_msi(ics
, srcno
, val
);
477 static void ics_write_xive_msi(ICSState
*ics
, int srcno
)
479 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
481 if (!(irq
->status
& XICS_STATUS_MASKED_PENDING
)
482 || (irq
->priority
== 0xff)) {
486 irq
->status
&= ~XICS_STATUS_MASKED_PENDING
;
487 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
490 static void ics_write_xive_lsi(ICSState
*ics
, int srcno
)
492 ics_resend_lsi(ics
, srcno
);
495 void ics_write_xive(ICSState
*ics
, int srcno
, int server
,
496 uint8_t priority
, uint8_t saved_priority
)
498 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
500 irq
->server
= server
;
501 irq
->priority
= priority
;
502 irq
->saved_priority
= saved_priority
;
504 trace_xics_ics_write_xive(ics
->offset
+ srcno
, srcno
, server
, priority
);
506 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
507 ics_write_xive_lsi(ics
, srcno
);
509 ics_write_xive_msi(ics
, srcno
);
513 static void ics_reject(ICSState
*ics
, uint32_t nr
)
515 ICSIRQState
*irq
= ics
->irqs
+ nr
- ics
->offset
;
517 trace_xics_ics_reject(nr
, nr
- ics
->offset
);
518 if (irq
->flags
& XICS_FLAGS_IRQ_MSI
) {
519 irq
->status
|= XICS_STATUS_REJECTED
;
520 } else if (irq
->flags
& XICS_FLAGS_IRQ_LSI
) {
521 irq
->status
&= ~XICS_STATUS_SENT
;
525 void ics_resend(ICSState
*ics
)
529 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
530 /* FIXME: filter by server#? */
531 if (ics
->irqs
[i
].flags
& XICS_FLAGS_IRQ_LSI
) {
532 ics_resend_lsi(ics
, i
);
534 ics_resend_msi(ics
, i
);
539 static void ics_eoi(ICSState
*ics
, uint32_t nr
)
541 int srcno
= nr
- ics
->offset
;
542 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
544 trace_xics_ics_eoi(nr
);
546 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
547 irq
->status
&= ~XICS_STATUS_SENT
;
551 static void ics_reset_irq(ICSIRQState
*irq
)
553 irq
->priority
= 0xff;
554 irq
->saved_priority
= 0xff;
557 static void ics_reset(DeviceState
*dev
)
559 ICSState
*ics
= ICS(dev
);
561 uint8_t flags
[ics
->nr_irqs
];
563 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
564 flags
[i
] = ics
->irqs
[i
].flags
;
567 memset(ics
->irqs
, 0, sizeof(ICSIRQState
) * ics
->nr_irqs
);
569 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
570 ics_reset_irq(ics
->irqs
+ i
);
571 ics
->irqs
[i
].flags
= flags
[i
];
574 if (kvm_irqchip_in_kernel()) {
575 Error
*local_err
= NULL
;
577 ics_set_kvm_state(ICS(dev
), &local_err
);
579 error_report_err(local_err
);
584 static void ics_reset_handler(void *dev
)
589 static void ics_realize(DeviceState
*dev
, Error
**errp
)
591 ICSState
*ics
= ICS(dev
);
592 Error
*local_err
= NULL
;
595 obj
= object_property_get_link(OBJECT(dev
), ICS_PROP_XICS
, &local_err
);
597 error_propagate_prepend(errp
, local_err
,
598 "required link '" ICS_PROP_XICS
602 ics
->xics
= XICS_FABRIC(obj
);
605 error_setg(errp
, "Number of interrupts needs to be greater 0");
608 ics
->irqs
= g_malloc0(ics
->nr_irqs
* sizeof(ICSIRQState
));
610 qemu_register_reset(ics_reset_handler
, ics
);
613 static void ics_instance_init(Object
*obj
)
615 ICSState
*ics
= ICS(obj
);
617 ics
->offset
= XICS_IRQ_BASE
;
620 static int ics_pre_save(void *opaque
)
622 ICSState
*ics
= opaque
;
624 if (kvm_irqchip_in_kernel()) {
625 ics_get_kvm_state(ics
);
631 static int ics_post_load(void *opaque
, int version_id
)
633 ICSState
*ics
= opaque
;
635 if (kvm_irqchip_in_kernel()) {
636 Error
*local_err
= NULL
;
639 ret
= ics_set_kvm_state(ics
, &local_err
);
641 error_report_err(local_err
);
649 static const VMStateDescription vmstate_ics_irq
= {
652 .minimum_version_id
= 1,
653 .fields
= (VMStateField
[]) {
654 VMSTATE_UINT32(server
, ICSIRQState
),
655 VMSTATE_UINT8(priority
, ICSIRQState
),
656 VMSTATE_UINT8(saved_priority
, ICSIRQState
),
657 VMSTATE_UINT8(status
, ICSIRQState
),
658 VMSTATE_UINT8(flags
, ICSIRQState
),
659 VMSTATE_END_OF_LIST()
663 static const VMStateDescription vmstate_ics
= {
666 .minimum_version_id
= 1,
667 .pre_save
= ics_pre_save
,
668 .post_load
= ics_post_load
,
669 .fields
= (VMStateField
[]) {
671 VMSTATE_UINT32_EQUAL(nr_irqs
, ICSState
, NULL
),
673 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs
, ICSState
, nr_irqs
,
676 VMSTATE_END_OF_LIST()
680 static Property ics_properties
[] = {
681 DEFINE_PROP_UINT32("nr-irqs", ICSState
, nr_irqs
, 0),
682 DEFINE_PROP_END_OF_LIST(),
685 static void ics_class_init(ObjectClass
*klass
, void *data
)
687 DeviceClass
*dc
= DEVICE_CLASS(klass
);
689 dc
->realize
= ics_realize
;
690 dc
->props
= ics_properties
;
691 dc
->reset
= ics_reset
;
692 dc
->vmsd
= &vmstate_ics
;
694 * Reason: part of XICS interrupt controller, needs to be wired up,
695 * e.g. by spapr_irq_init().
697 dc
->user_creatable
= false;
700 static const TypeInfo ics_info
= {
702 .parent
= TYPE_DEVICE
,
703 .instance_size
= sizeof(ICSState
),
704 .instance_init
= ics_instance_init
,
705 .class_init
= ics_class_init
,
706 .class_size
= sizeof(ICSStateClass
),
709 static const TypeInfo xics_fabric_info
= {
710 .name
= TYPE_XICS_FABRIC
,
711 .parent
= TYPE_INTERFACE
,
712 .class_size
= sizeof(XICSFabricClass
),
718 ICPState
*xics_icp_get(XICSFabric
*xi
, int server
)
720 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
722 return xic
->icp_get(xi
, server
);
725 void ics_set_irq_type(ICSState
*ics
, int srcno
, bool lsi
)
727 assert(!(ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_MASK
));
729 ics
->irqs
[srcno
].flags
|=
730 lsi
? XICS_FLAGS_IRQ_LSI
: XICS_FLAGS_IRQ_MSI
;
732 if (kvm_irqchip_in_kernel()) {
733 Error
*local_err
= NULL
;
735 ics_reset_irq(ics
->irqs
+ srcno
);
736 ics_set_kvm_state_one(ics
, srcno
, &local_err
);
738 error_report_err(local_err
);
743 static void xics_register_types(void)
745 type_register_static(&ics_info
);
746 type_register_static(&icp_info
);
747 type_register_static(&xics_fabric_info
);
750 type_init(xics_register_types
)