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 int xics_get_cpu_index_by_dt_id(int cpu_dt_id
)
43 PowerPCCPU
*cpu
= ppc_get_vcpu_by_dt_id(cpu_dt_id
);
46 return cpu
->parent_obj
.cpu_index
;
52 void xics_cpu_destroy(XICSState
*xics
, PowerPCCPU
*cpu
)
54 CPUState
*cs
= CPU(cpu
);
55 ICPState
*ss
= &xics
->ss
[cs
->cpu_index
];
57 assert(cs
->cpu_index
< xics
->nr_servers
);
64 void xics_cpu_setup(XICSState
*xics
, PowerPCCPU
*cpu
)
66 CPUState
*cs
= CPU(cpu
);
67 CPUPPCState
*env
= &cpu
->env
;
68 ICPState
*ss
= &xics
->ss
[cs
->cpu_index
];
69 XICSStateClass
*info
= XICS_COMMON_GET_CLASS(xics
);
71 assert(cs
->cpu_index
< xics
->nr_servers
);
75 if (info
->cpu_setup
) {
76 info
->cpu_setup(xics
, cpu
);
79 switch (PPC_INPUT(env
)) {
80 case PPC_FLAGS_INPUT_POWER7
:
81 ss
->output
= env
->irq_inputs
[POWER7_INPUT_INT
];
84 case PPC_FLAGS_INPUT_970
:
85 ss
->output
= env
->irq_inputs
[PPC970_INPUT_INT
];
89 error_report("XICS interrupt controller does not support this CPU "
95 static void icp_pic_print_info(InterruptStatsProvider
*obj
,
98 ICPState
*icp
= ICP(obj
);
99 int cpu_index
= icp
->cs
? icp
->cs
->cpu_index
: -1;
104 monitor_printf(mon
, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
105 cpu_index
, icp
->xirr
, icp
->xirr_owner
,
106 icp
->pending_priority
, icp
->mfrr
);
109 static void ics_simple_pic_print_info(InterruptStatsProvider
*obj
,
112 ICSState
*ics
= ICS_SIMPLE(obj
);
115 monitor_printf(mon
, "ICS %4x..%4x %p\n",
116 ics
->offset
, ics
->offset
+ ics
->nr_irqs
- 1, ics
);
122 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
123 ICSIRQState
*irq
= ics
->irqs
+ i
;
125 if (!(irq
->flags
& XICS_FLAGS_IRQ_MASK
)) {
128 monitor_printf(mon
, " %4x %s %02x %02x\n",
130 (irq
->flags
& XICS_FLAGS_IRQ_LSI
) ?
132 irq
->priority
, irq
->status
);
137 * XICS Common class - parent for emulated XICS and KVM-XICS
139 static void xics_common_reset(DeviceState
*d
)
141 XICSState
*xics
= XICS_COMMON(d
);
145 for (i
= 0; i
< xics
->nr_servers
; i
++) {
146 device_reset(DEVICE(&xics
->ss
[i
]));
149 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
150 device_reset(DEVICE(ics
));
154 static void xics_common_initfn(Object
*obj
)
156 XICSState
*xics
= XICS_COMMON(obj
);
158 QLIST_INIT(&xics
->ics
);
161 static void xics_common_class_init(ObjectClass
*oc
, void *data
)
163 DeviceClass
*dc
= DEVICE_CLASS(oc
);
165 dc
->reset
= xics_common_reset
;
168 static const TypeInfo xics_common_info
= {
169 .name
= TYPE_XICS_COMMON
,
170 .parent
= TYPE_DEVICE
,
171 .instance_size
= sizeof(XICSState
),
172 .class_size
= sizeof(XICSStateClass
),
173 .instance_init
= xics_common_initfn
,
174 .class_init
= xics_common_class_init
,
178 * ICP: Presentation layer
181 #define XISR_MASK 0x00ffffff
182 #define CPPR_MASK 0xff000000
184 #define XISR(ss) (((ss)->xirr) & XISR_MASK)
185 #define CPPR(ss) (((ss)->xirr) >> 24)
187 static void ics_reject(ICSState
*ics
, uint32_t nr
)
189 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
196 void ics_resend(ICSState
*ics
)
198 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
205 static void ics_eoi(ICSState
*ics
, int nr
)
207 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
214 static void icp_check_ipi(ICPState
*ss
)
216 if (XISR(ss
) && (ss
->pending_priority
<= ss
->mfrr
)) {
220 trace_xics_icp_check_ipi(ss
->cs
->cpu_index
, ss
->mfrr
);
222 if (XISR(ss
) && ss
->xirr_owner
) {
223 ics_reject(ss
->xirr_owner
, XISR(ss
));
226 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | XICS_IPI
;
227 ss
->pending_priority
= ss
->mfrr
;
228 ss
->xirr_owner
= NULL
;
229 qemu_irq_raise(ss
->output
);
232 static void icp_resend(ICPState
*ss
)
236 if (ss
->mfrr
< CPPR(ss
)) {
239 QLIST_FOREACH(ics
, &ss
->xics
->ics
, list
) {
244 void icp_set_cppr(ICPState
*ss
, uint8_t cppr
)
250 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (cppr
<< 24);
252 if (cppr
< old_cppr
) {
253 if (XISR(ss
) && (cppr
<= ss
->pending_priority
)) {
255 ss
->xirr
&= ~XISR_MASK
; /* Clear XISR */
256 ss
->pending_priority
= 0xff;
257 qemu_irq_lower(ss
->output
);
258 if (ss
->xirr_owner
) {
259 ics_reject(ss
->xirr_owner
, old_xisr
);
260 ss
->xirr_owner
= NULL
;
270 void icp_set_mfrr(ICPState
*ss
, uint8_t mfrr
)
273 if (mfrr
< CPPR(ss
)) {
278 uint32_t icp_accept(ICPState
*ss
)
280 uint32_t xirr
= ss
->xirr
;
282 qemu_irq_lower(ss
->output
);
283 ss
->xirr
= ss
->pending_priority
<< 24;
284 ss
->pending_priority
= 0xff;
285 ss
->xirr_owner
= NULL
;
287 trace_xics_icp_accept(xirr
, ss
->xirr
);
292 uint32_t icp_ipoll(ICPState
*ss
, uint32_t *mfrr
)
300 void icp_eoi(ICPState
*ss
, uint32_t xirr
)
305 /* Send EOI -> ICS */
306 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (xirr
& CPPR_MASK
);
307 trace_xics_icp_eoi(ss
->cs
->cpu_index
, xirr
, ss
->xirr
);
308 irq
= xirr
& XISR_MASK
;
309 QLIST_FOREACH(ics
, &ss
->xics
->ics
, list
) {
310 if (ics_valid_irq(ics
, irq
)) {
319 static void icp_irq(ICSState
*ics
, int server
, int nr
, uint8_t priority
)
321 XICSState
*xics
= ics
->xics
;
322 ICPState
*ss
= xics
->ss
+ server
;
324 trace_xics_icp_irq(server
, nr
, priority
);
326 if ((priority
>= CPPR(ss
))
327 || (XISR(ss
) && (ss
->pending_priority
<= priority
))) {
330 if (XISR(ss
) && ss
->xirr_owner
) {
331 ics_reject(ss
->xirr_owner
, XISR(ss
));
332 ss
->xirr_owner
= NULL
;
334 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | (nr
& XISR_MASK
);
335 ss
->xirr_owner
= ics
;
336 ss
->pending_priority
= priority
;
337 trace_xics_icp_raise(ss
->xirr
, ss
->pending_priority
);
338 qemu_irq_raise(ss
->output
);
342 static void icp_dispatch_pre_save(void *opaque
)
344 ICPState
*ss
= opaque
;
345 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
347 if (info
->pre_save
) {
352 static int icp_dispatch_post_load(void *opaque
, int version_id
)
354 ICPState
*ss
= opaque
;
355 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
357 if (info
->post_load
) {
358 return info
->post_load(ss
, version_id
);
364 static const VMStateDescription vmstate_icp_server
= {
365 .name
= "icp/server",
367 .minimum_version_id
= 1,
368 .pre_save
= icp_dispatch_pre_save
,
369 .post_load
= icp_dispatch_post_load
,
370 .fields
= (VMStateField
[]) {
372 VMSTATE_UINT32(xirr
, ICPState
),
373 VMSTATE_UINT8(pending_priority
, ICPState
),
374 VMSTATE_UINT8(mfrr
, ICPState
),
375 VMSTATE_END_OF_LIST()
379 static void icp_reset(DeviceState
*dev
)
381 ICPState
*icp
= ICP(dev
);
384 icp
->pending_priority
= 0xff;
387 /* Make all outputs are deasserted */
388 qemu_set_irq(icp
->output
, 0);
391 static void icp_realize(DeviceState
*dev
, Error
**errp
)
393 ICPState
*icp
= ICP(dev
);
397 obj
= object_property_get_link(OBJECT(dev
), "xics", &err
);
399 error_setg(errp
, "%s: required link 'xics' not found: %s",
400 __func__
, error_get_pretty(err
));
404 icp
->xics
= XICS_COMMON(obj
);
408 static void icp_class_init(ObjectClass
*klass
, void *data
)
410 DeviceClass
*dc
= DEVICE_CLASS(klass
);
411 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
413 dc
->reset
= icp_reset
;
414 dc
->vmsd
= &vmstate_icp_server
;
415 dc
->realize
= icp_realize
;
416 ic
->print_info
= icp_pic_print_info
;
419 static const TypeInfo icp_info
= {
421 .parent
= TYPE_DEVICE
,
422 .instance_size
= sizeof(ICPState
),
423 .class_init
= icp_class_init
,
424 .class_size
= sizeof(ICPStateClass
),
425 .interfaces
= (InterfaceInfo
[]) {
426 { TYPE_INTERRUPT_STATS_PROVIDER
},
434 static void ics_simple_resend_msi(ICSState
*ics
, int srcno
)
436 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
438 /* FIXME: filter by server#? */
439 if (irq
->status
& XICS_STATUS_REJECTED
) {
440 irq
->status
&= ~XICS_STATUS_REJECTED
;
441 if (irq
->priority
!= 0xff) {
442 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
447 static void ics_simple_resend_lsi(ICSState
*ics
, int srcno
)
449 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
451 if ((irq
->priority
!= 0xff)
452 && (irq
->status
& XICS_STATUS_ASSERTED
)
453 && !(irq
->status
& XICS_STATUS_SENT
)) {
454 irq
->status
|= XICS_STATUS_SENT
;
455 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
459 static void ics_simple_set_irq_msi(ICSState
*ics
, int srcno
, int val
)
461 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
463 trace_xics_ics_simple_set_irq_msi(srcno
, srcno
+ ics
->offset
);
466 if (irq
->priority
== 0xff) {
467 irq
->status
|= XICS_STATUS_MASKED_PENDING
;
468 trace_xics_masked_pending();
470 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
475 static void ics_simple_set_irq_lsi(ICSState
*ics
, int srcno
, int val
)
477 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
479 trace_xics_ics_simple_set_irq_lsi(srcno
, srcno
+ ics
->offset
);
481 irq
->status
|= XICS_STATUS_ASSERTED
;
483 irq
->status
&= ~XICS_STATUS_ASSERTED
;
485 ics_simple_resend_lsi(ics
, srcno
);
488 static void ics_simple_set_irq(void *opaque
, int srcno
, int val
)
490 ICSState
*ics
= (ICSState
*)opaque
;
492 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
493 ics_simple_set_irq_lsi(ics
, srcno
, val
);
495 ics_simple_set_irq_msi(ics
, srcno
, val
);
499 static void ics_simple_write_xive_msi(ICSState
*ics
, int srcno
)
501 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
503 if (!(irq
->status
& XICS_STATUS_MASKED_PENDING
)
504 || (irq
->priority
== 0xff)) {
508 irq
->status
&= ~XICS_STATUS_MASKED_PENDING
;
509 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
512 static void ics_simple_write_xive_lsi(ICSState
*ics
, int srcno
)
514 ics_simple_resend_lsi(ics
, srcno
);
517 void ics_simple_write_xive(ICSState
*ics
, int srcno
, int server
,
518 uint8_t priority
, uint8_t saved_priority
)
520 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
522 irq
->server
= server
;
523 irq
->priority
= priority
;
524 irq
->saved_priority
= saved_priority
;
526 trace_xics_ics_simple_write_xive(ics
->offset
+ srcno
, srcno
, server
,
529 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
530 ics_simple_write_xive_lsi(ics
, srcno
);
532 ics_simple_write_xive_msi(ics
, srcno
);
536 static void ics_simple_reject(ICSState
*ics
, uint32_t nr
)
538 ICSIRQState
*irq
= ics
->irqs
+ nr
- ics
->offset
;
540 trace_xics_ics_simple_reject(nr
, nr
- ics
->offset
);
541 if (irq
->flags
& XICS_FLAGS_IRQ_MSI
) {
542 irq
->status
|= XICS_STATUS_REJECTED
;
543 } else if (irq
->flags
& XICS_FLAGS_IRQ_LSI
) {
544 irq
->status
&= ~XICS_STATUS_SENT
;
548 static void ics_simple_resend(ICSState
*ics
)
552 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
553 /* FIXME: filter by server#? */
554 if (ics
->irqs
[i
].flags
& XICS_FLAGS_IRQ_LSI
) {
555 ics_simple_resend_lsi(ics
, i
);
557 ics_simple_resend_msi(ics
, i
);
562 static void ics_simple_eoi(ICSState
*ics
, uint32_t nr
)
564 int srcno
= nr
- ics
->offset
;
565 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
567 trace_xics_ics_simple_eoi(nr
);
569 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
570 irq
->status
&= ~XICS_STATUS_SENT
;
574 static void ics_simple_reset(DeviceState
*dev
)
576 ICSState
*ics
= ICS_SIMPLE(dev
);
578 uint8_t flags
[ics
->nr_irqs
];
580 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
581 flags
[i
] = ics
->irqs
[i
].flags
;
584 memset(ics
->irqs
, 0, sizeof(ICSIRQState
) * ics
->nr_irqs
);
586 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
587 ics
->irqs
[i
].priority
= 0xff;
588 ics
->irqs
[i
].saved_priority
= 0xff;
589 ics
->irqs
[i
].flags
= flags
[i
];
593 static int ics_simple_post_load(ICSState
*ics
, int version_id
)
597 for (i
= 0; i
< ics
->xics
->nr_servers
; i
++) {
598 icp_resend(&ics
->xics
->ss
[i
]);
604 static void ics_simple_dispatch_pre_save(void *opaque
)
606 ICSState
*ics
= opaque
;
607 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
609 if (info
->pre_save
) {
614 static int ics_simple_dispatch_post_load(void *opaque
, int version_id
)
616 ICSState
*ics
= opaque
;
617 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
619 if (info
->post_load
) {
620 return info
->post_load(ics
, version_id
);
626 static const VMStateDescription vmstate_ics_simple_irq
= {
629 .minimum_version_id
= 1,
630 .fields
= (VMStateField
[]) {
631 VMSTATE_UINT32(server
, ICSIRQState
),
632 VMSTATE_UINT8(priority
, ICSIRQState
),
633 VMSTATE_UINT8(saved_priority
, ICSIRQState
),
634 VMSTATE_UINT8(status
, ICSIRQState
),
635 VMSTATE_UINT8(flags
, ICSIRQState
),
636 VMSTATE_END_OF_LIST()
640 static const VMStateDescription vmstate_ics_simple
= {
643 .minimum_version_id
= 1,
644 .pre_save
= ics_simple_dispatch_pre_save
,
645 .post_load
= ics_simple_dispatch_post_load
,
646 .fields
= (VMStateField
[]) {
648 VMSTATE_UINT32_EQUAL(nr_irqs
, ICSState
),
650 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs
, ICSState
, nr_irqs
,
651 vmstate_ics_simple_irq
,
653 VMSTATE_END_OF_LIST()
657 static void ics_simple_initfn(Object
*obj
)
659 ICSState
*ics
= ICS_SIMPLE(obj
);
661 ics
->offset
= XICS_IRQ_BASE
;
664 static void ics_simple_realize(DeviceState
*dev
, Error
**errp
)
666 ICSState
*ics
= ICS_SIMPLE(dev
);
669 error_setg(errp
, "Number of interrupts needs to be greater 0");
672 ics
->irqs
= g_malloc0(ics
->nr_irqs
* sizeof(ICSIRQState
));
673 ics
->qirqs
= qemu_allocate_irqs(ics_simple_set_irq
, ics
, ics
->nr_irqs
);
676 static Property ics_simple_properties
[] = {
677 DEFINE_PROP_UINT32("nr-irqs", ICSState
, nr_irqs
, 0),
678 DEFINE_PROP_END_OF_LIST(),
681 static void ics_simple_class_init(ObjectClass
*klass
, void *data
)
683 DeviceClass
*dc
= DEVICE_CLASS(klass
);
684 ICSStateClass
*isc
= ICS_BASE_CLASS(klass
);
685 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
687 isc
->realize
= ics_simple_realize
;
688 dc
->props
= ics_simple_properties
;
689 dc
->vmsd
= &vmstate_ics_simple
;
690 dc
->reset
= ics_simple_reset
;
691 isc
->post_load
= ics_simple_post_load
;
692 isc
->reject
= ics_simple_reject
;
693 isc
->resend
= ics_simple_resend
;
694 isc
->eoi
= ics_simple_eoi
;
695 ic
->print_info
= ics_simple_pic_print_info
;
698 static const TypeInfo ics_simple_info
= {
699 .name
= TYPE_ICS_SIMPLE
,
700 .parent
= TYPE_ICS_BASE
,
701 .instance_size
= sizeof(ICSState
),
702 .class_init
= ics_simple_class_init
,
703 .class_size
= sizeof(ICSStateClass
),
704 .instance_init
= ics_simple_initfn
,
705 .interfaces
= (InterfaceInfo
[]) {
706 { TYPE_INTERRUPT_STATS_PROVIDER
},
711 static void ics_base_realize(DeviceState
*dev
, Error
**errp
)
713 ICSStateClass
*icsc
= ICS_BASE_GET_CLASS(dev
);
714 ICSState
*ics
= ICS_BASE(dev
);
718 obj
= object_property_get_link(OBJECT(dev
), "xics", &err
);
720 error_setg(errp
, "%s: required link 'xics' not found: %s",
721 __func__
, error_get_pretty(err
));
724 ics
->xics
= XICS_COMMON(obj
);
728 icsc
->realize(dev
, errp
);
732 static void ics_base_class_init(ObjectClass
*klass
, void *data
)
734 DeviceClass
*dc
= DEVICE_CLASS(klass
);
736 dc
->realize
= ics_base_realize
;
739 static const TypeInfo ics_base_info
= {
740 .name
= TYPE_ICS_BASE
,
741 .parent
= TYPE_DEVICE
,
743 .instance_size
= sizeof(ICSState
),
744 .class_init
= ics_base_class_init
,
745 .class_size
= sizeof(ICSStateClass
),
748 static const TypeInfo xics_fabric_info
= {
749 .name
= TYPE_XICS_FABRIC
,
750 .parent
= TYPE_INTERFACE
,
751 .class_size
= sizeof(XICSFabricClass
),
757 ICSState
*xics_find_source(XICSState
*xics
, int irq
)
761 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
762 if (ics_valid_irq(ics
, irq
)) {
769 qemu_irq
xics_get_qirq(XICSFabric
*xi
, int irq
)
771 XICSFabricClass
*xic
= XICS_FABRIC_GET_CLASS(xi
);
772 ICSState
*ics
= xic
->ics_get(xi
, irq
);
775 return ics
->qirqs
[irq
- ics
->offset
];
781 void ics_set_irq_type(ICSState
*ics
, int srcno
, bool lsi
)
783 assert(!(ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_MASK
));
785 ics
->irqs
[srcno
].flags
|=
786 lsi
? XICS_FLAGS_IRQ_LSI
: XICS_FLAGS_IRQ_MSI
;
789 static void xics_register_types(void)
791 type_register_static(&xics_common_info
);
792 type_register_static(&ics_simple_info
);
793 type_register_static(&ics_base_info
);
794 type_register_static(&icp_info
);
795 type_register_static(&xics_fabric_info
);
798 type_init(xics_register_types
)