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"
39 int xics_get_cpu_index_by_dt_id(int cpu_dt_id
)
41 PowerPCCPU
*cpu
= ppc_get_vcpu_by_dt_id(cpu_dt_id
);
44 return cpu
->parent_obj
.cpu_index
;
50 void xics_cpu_destroy(XICSState
*xics
, PowerPCCPU
*cpu
)
52 CPUState
*cs
= CPU(cpu
);
53 ICPState
*ss
= &xics
->ss
[cs
->cpu_index
];
55 assert(cs
->cpu_index
< xics
->nr_servers
);
62 void xics_cpu_setup(XICSState
*xics
, PowerPCCPU
*cpu
)
64 CPUState
*cs
= CPU(cpu
);
65 CPUPPCState
*env
= &cpu
->env
;
66 ICPState
*ss
= &xics
->ss
[cs
->cpu_index
];
67 XICSStateClass
*info
= XICS_COMMON_GET_CLASS(xics
);
69 assert(cs
->cpu_index
< xics
->nr_servers
);
73 if (info
->cpu_setup
) {
74 info
->cpu_setup(xics
, cpu
);
77 switch (PPC_INPUT(env
)) {
78 case PPC_FLAGS_INPUT_POWER7
:
79 ss
->output
= env
->irq_inputs
[POWER7_INPUT_INT
];
82 case PPC_FLAGS_INPUT_970
:
83 ss
->output
= env
->irq_inputs
[PPC970_INPUT_INT
];
87 error_report("XICS interrupt controller does not support this CPU "
94 * XICS Common class - parent for emulated XICS and KVM-XICS
96 static void xics_common_reset(DeviceState
*d
)
98 XICSState
*xics
= XICS_COMMON(d
);
102 for (i
= 0; i
< xics
->nr_servers
; i
++) {
103 device_reset(DEVICE(&xics
->ss
[i
]));
106 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
107 device_reset(DEVICE(ics
));
111 static void xics_prop_get_nr_irqs(Object
*obj
, Visitor
*v
, const char *name
,
112 void *opaque
, Error
**errp
)
114 XICSState
*xics
= XICS_COMMON(obj
);
115 int64_t value
= xics
->nr_irqs
;
117 visit_type_int(v
, name
, &value
, errp
);
120 static void xics_prop_set_nr_irqs(Object
*obj
, Visitor
*v
, const char *name
,
121 void *opaque
, Error
**errp
)
123 XICSState
*xics
= XICS_COMMON(obj
);
124 XICSStateClass
*info
= XICS_COMMON_GET_CLASS(xics
);
128 visit_type_int(v
, name
, &value
, &error
);
130 error_propagate(errp
, error
);
134 error_setg(errp
, "Number of interrupts is already set to %u",
139 assert(info
->set_nr_irqs
);
140 info
->set_nr_irqs(xics
, value
, errp
);
143 static void xics_prop_get_nr_servers(Object
*obj
, Visitor
*v
,
144 const char *name
, void *opaque
,
147 XICSState
*xics
= XICS_COMMON(obj
);
148 int64_t value
= xics
->nr_servers
;
150 visit_type_int(v
, name
, &value
, errp
);
153 static void xics_prop_set_nr_servers(Object
*obj
, Visitor
*v
,
154 const char *name
, void *opaque
,
157 XICSState
*xics
= XICS_COMMON(obj
);
158 XICSStateClass
*info
= XICS_COMMON_GET_CLASS(xics
);
162 visit_type_int(v
, name
, &value
, &error
);
164 error_propagate(errp
, error
);
167 if (xics
->nr_servers
) {
168 error_setg(errp
, "Number of servers is already set to %u",
173 assert(info
->set_nr_servers
);
174 info
->set_nr_servers(xics
, value
, errp
);
177 static void xics_common_initfn(Object
*obj
)
179 XICSState
*xics
= XICS_COMMON(obj
);
181 QLIST_INIT(&xics
->ics
);
182 object_property_add(obj
, "nr_irqs", "int",
183 xics_prop_get_nr_irqs
, xics_prop_set_nr_irqs
,
185 object_property_add(obj
, "nr_servers", "int",
186 xics_prop_get_nr_servers
, xics_prop_set_nr_servers
,
190 static void xics_common_class_init(ObjectClass
*oc
, void *data
)
192 DeviceClass
*dc
= DEVICE_CLASS(oc
);
194 dc
->reset
= xics_common_reset
;
197 static const TypeInfo xics_common_info
= {
198 .name
= TYPE_XICS_COMMON
,
199 .parent
= TYPE_SYS_BUS_DEVICE
,
200 .instance_size
= sizeof(XICSState
),
201 .class_size
= sizeof(XICSStateClass
),
202 .instance_init
= xics_common_initfn
,
203 .class_init
= xics_common_class_init
,
207 * ICP: Presentation layer
210 #define XISR_MASK 0x00ffffff
211 #define CPPR_MASK 0xff000000
213 #define XISR(ss) (((ss)->xirr) & XISR_MASK)
214 #define CPPR(ss) (((ss)->xirr) >> 24)
216 static void ics_reject(ICSState
*ics
, uint32_t nr
)
218 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
225 static void ics_resend(ICSState
*ics
)
227 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
234 static void ics_eoi(ICSState
*ics
, int nr
)
236 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
243 static void icp_check_ipi(ICPState
*ss
)
245 if (XISR(ss
) && (ss
->pending_priority
<= ss
->mfrr
)) {
249 trace_xics_icp_check_ipi(ss
->cs
->cpu_index
, ss
->mfrr
);
251 if (XISR(ss
) && ss
->xirr_owner
) {
252 ics_reject(ss
->xirr_owner
, XISR(ss
));
255 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | XICS_IPI
;
256 ss
->pending_priority
= ss
->mfrr
;
257 ss
->xirr_owner
= NULL
;
258 qemu_irq_raise(ss
->output
);
261 static void icp_resend(XICSState
*xics
, int server
)
263 ICPState
*ss
= xics
->ss
+ server
;
266 if (ss
->mfrr
< CPPR(ss
)) {
269 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
274 void icp_set_cppr(XICSState
*xics
, int server
, uint8_t cppr
)
276 ICPState
*ss
= xics
->ss
+ server
;
281 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (cppr
<< 24);
283 if (cppr
< old_cppr
) {
284 if (XISR(ss
) && (cppr
<= ss
->pending_priority
)) {
286 ss
->xirr
&= ~XISR_MASK
; /* Clear XISR */
287 ss
->pending_priority
= 0xff;
288 qemu_irq_lower(ss
->output
);
289 if (ss
->xirr_owner
) {
290 ics_reject(ss
->xirr_owner
, old_xisr
);
291 ss
->xirr_owner
= NULL
;
296 icp_resend(xics
, server
);
301 void icp_set_mfrr(XICSState
*xics
, int server
, uint8_t mfrr
)
303 ICPState
*ss
= xics
->ss
+ server
;
306 if (mfrr
< CPPR(ss
)) {
311 uint32_t icp_accept(ICPState
*ss
)
313 uint32_t xirr
= ss
->xirr
;
315 qemu_irq_lower(ss
->output
);
316 ss
->xirr
= ss
->pending_priority
<< 24;
317 ss
->pending_priority
= 0xff;
318 ss
->xirr_owner
= NULL
;
320 trace_xics_icp_accept(xirr
, ss
->xirr
);
325 uint32_t icp_ipoll(ICPState
*ss
, uint32_t *mfrr
)
333 void icp_eoi(XICSState
*xics
, int server
, uint32_t xirr
)
335 ICPState
*ss
= xics
->ss
+ server
;
339 /* Send EOI -> ICS */
340 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (xirr
& CPPR_MASK
);
341 trace_xics_icp_eoi(server
, xirr
, ss
->xirr
);
342 irq
= xirr
& XISR_MASK
;
343 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
344 if (ics_valid_irq(ics
, irq
)) {
349 icp_resend(xics
, server
);
353 static void icp_irq(ICSState
*ics
, int server
, int nr
, uint8_t priority
)
355 XICSState
*xics
= ics
->xics
;
356 ICPState
*ss
= xics
->ss
+ server
;
358 trace_xics_icp_irq(server
, nr
, priority
);
360 if ((priority
>= CPPR(ss
))
361 || (XISR(ss
) && (ss
->pending_priority
<= priority
))) {
364 if (XISR(ss
) && ss
->xirr_owner
) {
365 ics_reject(ss
->xirr_owner
, XISR(ss
));
366 ss
->xirr_owner
= NULL
;
368 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | (nr
& XISR_MASK
);
369 ss
->xirr_owner
= ics
;
370 ss
->pending_priority
= priority
;
371 trace_xics_icp_raise(ss
->xirr
, ss
->pending_priority
);
372 qemu_irq_raise(ss
->output
);
376 static void icp_dispatch_pre_save(void *opaque
)
378 ICPState
*ss
= opaque
;
379 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
381 if (info
->pre_save
) {
386 static int icp_dispatch_post_load(void *opaque
, int version_id
)
388 ICPState
*ss
= opaque
;
389 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
391 if (info
->post_load
) {
392 return info
->post_load(ss
, version_id
);
398 static const VMStateDescription vmstate_icp_server
= {
399 .name
= "icp/server",
401 .minimum_version_id
= 1,
402 .pre_save
= icp_dispatch_pre_save
,
403 .post_load
= icp_dispatch_post_load
,
404 .fields
= (VMStateField
[]) {
406 VMSTATE_UINT32(xirr
, ICPState
),
407 VMSTATE_UINT8(pending_priority
, ICPState
),
408 VMSTATE_UINT8(mfrr
, ICPState
),
409 VMSTATE_END_OF_LIST()
413 static void icp_reset(DeviceState
*dev
)
415 ICPState
*icp
= ICP(dev
);
418 icp
->pending_priority
= 0xff;
421 /* Make all outputs are deasserted */
422 qemu_set_irq(icp
->output
, 0);
425 static void icp_class_init(ObjectClass
*klass
, void *data
)
427 DeviceClass
*dc
= DEVICE_CLASS(klass
);
429 dc
->reset
= icp_reset
;
430 dc
->vmsd
= &vmstate_icp_server
;
433 static const TypeInfo icp_info
= {
435 .parent
= TYPE_DEVICE
,
436 .instance_size
= sizeof(ICPState
),
437 .class_init
= icp_class_init
,
438 .class_size
= sizeof(ICPStateClass
),
444 static void ics_simple_resend_msi(ICSState
*ics
, int srcno
)
446 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
448 /* FIXME: filter by server#? */
449 if (irq
->status
& XICS_STATUS_REJECTED
) {
450 irq
->status
&= ~XICS_STATUS_REJECTED
;
451 if (irq
->priority
!= 0xff) {
452 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
457 static void ics_simple_resend_lsi(ICSState
*ics
, int srcno
)
459 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
461 if ((irq
->priority
!= 0xff)
462 && (irq
->status
& XICS_STATUS_ASSERTED
)
463 && !(irq
->status
& XICS_STATUS_SENT
)) {
464 irq
->status
|= XICS_STATUS_SENT
;
465 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
469 static void ics_simple_set_irq_msi(ICSState
*ics
, int srcno
, int val
)
471 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
473 trace_xics_ics_simple_set_irq_msi(srcno
, srcno
+ ics
->offset
);
476 if (irq
->priority
== 0xff) {
477 irq
->status
|= XICS_STATUS_MASKED_PENDING
;
478 trace_xics_masked_pending();
480 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
485 static void ics_simple_set_irq_lsi(ICSState
*ics
, int srcno
, int val
)
487 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
489 trace_xics_ics_simple_set_irq_lsi(srcno
, srcno
+ ics
->offset
);
491 irq
->status
|= XICS_STATUS_ASSERTED
;
493 irq
->status
&= ~XICS_STATUS_ASSERTED
;
495 ics_simple_resend_lsi(ics
, srcno
);
498 static void ics_simple_set_irq(void *opaque
, int srcno
, int val
)
500 ICSState
*ics
= (ICSState
*)opaque
;
502 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
503 ics_simple_set_irq_lsi(ics
, srcno
, val
);
505 ics_simple_set_irq_msi(ics
, srcno
, val
);
509 static void ics_simple_write_xive_msi(ICSState
*ics
, int srcno
)
511 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
513 if (!(irq
->status
& XICS_STATUS_MASKED_PENDING
)
514 || (irq
->priority
== 0xff)) {
518 irq
->status
&= ~XICS_STATUS_MASKED_PENDING
;
519 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
522 static void ics_simple_write_xive_lsi(ICSState
*ics
, int srcno
)
524 ics_simple_resend_lsi(ics
, srcno
);
527 void ics_simple_write_xive(ICSState
*ics
, int srcno
, int server
,
528 uint8_t priority
, uint8_t saved_priority
)
530 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
532 irq
->server
= server
;
533 irq
->priority
= priority
;
534 irq
->saved_priority
= saved_priority
;
536 trace_xics_ics_simple_write_xive(ics
->offset
+ srcno
, srcno
, server
,
539 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
540 ics_simple_write_xive_lsi(ics
, srcno
);
542 ics_simple_write_xive_msi(ics
, srcno
);
546 static void ics_simple_reject(ICSState
*ics
, uint32_t nr
)
548 ICSIRQState
*irq
= ics
->irqs
+ nr
- ics
->offset
;
550 trace_xics_ics_simple_reject(nr
, nr
- ics
->offset
);
551 if (irq
->flags
& XICS_FLAGS_IRQ_MSI
) {
552 irq
->status
|= XICS_STATUS_REJECTED
;
553 } else if (irq
->flags
& XICS_FLAGS_IRQ_LSI
) {
554 irq
->status
&= ~XICS_STATUS_SENT
;
558 static void ics_simple_resend(ICSState
*ics
)
562 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
563 /* FIXME: filter by server#? */
564 if (ics
->irqs
[i
].flags
& XICS_FLAGS_IRQ_LSI
) {
565 ics_simple_resend_lsi(ics
, i
);
567 ics_simple_resend_msi(ics
, i
);
572 static void ics_simple_eoi(ICSState
*ics
, uint32_t nr
)
574 int srcno
= nr
- ics
->offset
;
575 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
577 trace_xics_ics_simple_eoi(nr
);
579 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
580 irq
->status
&= ~XICS_STATUS_SENT
;
584 static void ics_simple_reset(DeviceState
*dev
)
586 ICSState
*ics
= ICS_SIMPLE(dev
);
588 uint8_t flags
[ics
->nr_irqs
];
590 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
591 flags
[i
] = ics
->irqs
[i
].flags
;
594 memset(ics
->irqs
, 0, sizeof(ICSIRQState
) * ics
->nr_irqs
);
596 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
597 ics
->irqs
[i
].priority
= 0xff;
598 ics
->irqs
[i
].saved_priority
= 0xff;
599 ics
->irqs
[i
].flags
= flags
[i
];
603 static int ics_simple_post_load(ICSState
*ics
, int version_id
)
607 for (i
= 0; i
< ics
->xics
->nr_servers
; i
++) {
608 icp_resend(ics
->xics
, i
);
614 static void ics_simple_dispatch_pre_save(void *opaque
)
616 ICSState
*ics
= opaque
;
617 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
619 if (info
->pre_save
) {
624 static int ics_simple_dispatch_post_load(void *opaque
, int version_id
)
626 ICSState
*ics
= opaque
;
627 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
629 if (info
->post_load
) {
630 return info
->post_load(ics
, version_id
);
636 static const VMStateDescription vmstate_ics_simple_irq
= {
639 .minimum_version_id
= 1,
640 .fields
= (VMStateField
[]) {
641 VMSTATE_UINT32(server
, ICSIRQState
),
642 VMSTATE_UINT8(priority
, ICSIRQState
),
643 VMSTATE_UINT8(saved_priority
, ICSIRQState
),
644 VMSTATE_UINT8(status
, ICSIRQState
),
645 VMSTATE_UINT8(flags
, ICSIRQState
),
646 VMSTATE_END_OF_LIST()
650 static const VMStateDescription vmstate_ics_simple
= {
653 .minimum_version_id
= 1,
654 .pre_save
= ics_simple_dispatch_pre_save
,
655 .post_load
= ics_simple_dispatch_post_load
,
656 .fields
= (VMStateField
[]) {
658 VMSTATE_UINT32_EQUAL(nr_irqs
, ICSState
),
660 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs
, ICSState
, nr_irqs
,
661 vmstate_ics_simple_irq
,
663 VMSTATE_END_OF_LIST()
667 static void ics_simple_initfn(Object
*obj
)
669 ICSState
*ics
= ICS_SIMPLE(obj
);
671 ics
->offset
= XICS_IRQ_BASE
;
674 static void ics_simple_realize(DeviceState
*dev
, Error
**errp
)
676 ICSState
*ics
= ICS_SIMPLE(dev
);
679 error_setg(errp
, "Number of interrupts needs to be greater 0");
682 ics
->irqs
= g_malloc0(ics
->nr_irqs
* sizeof(ICSIRQState
));
683 ics
->qirqs
= qemu_allocate_irqs(ics_simple_set_irq
, ics
, ics
->nr_irqs
);
686 static void ics_simple_class_init(ObjectClass
*klass
, void *data
)
688 DeviceClass
*dc
= DEVICE_CLASS(klass
);
689 ICSStateClass
*isc
= ICS_BASE_CLASS(klass
);
691 dc
->realize
= ics_simple_realize
;
692 dc
->vmsd
= &vmstate_ics_simple
;
693 dc
->reset
= ics_simple_reset
;
694 isc
->post_load
= ics_simple_post_load
;
695 isc
->reject
= ics_simple_reject
;
696 isc
->resend
= ics_simple_resend
;
697 isc
->eoi
= ics_simple_eoi
;
700 static const TypeInfo ics_simple_info
= {
701 .name
= TYPE_ICS_SIMPLE
,
702 .parent
= TYPE_ICS_BASE
,
703 .instance_size
= sizeof(ICSState
),
704 .class_init
= ics_simple_class_init
,
705 .class_size
= sizeof(ICSStateClass
),
706 .instance_init
= ics_simple_initfn
,
709 static const TypeInfo ics_base_info
= {
710 .name
= TYPE_ICS_BASE
,
711 .parent
= TYPE_DEVICE
,
713 .instance_size
= sizeof(ICSState
),
714 .class_size
= sizeof(ICSStateClass
),
720 ICSState
*xics_find_source(XICSState
*xics
, int irq
)
724 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
725 if (ics_valid_irq(ics
, irq
)) {
732 qemu_irq
xics_get_qirq(XICSState
*xics
, int irq
)
734 ICSState
*ics
= xics_find_source(xics
, irq
);
737 return ics
->qirqs
[irq
- ics
->offset
];
743 void ics_set_irq_type(ICSState
*ics
, int srcno
, bool lsi
)
745 assert(!(ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_MASK
));
747 ics
->irqs
[srcno
].flags
|=
748 lsi
? XICS_FLAGS_IRQ_LSI
: XICS_FLAGS_IRQ_MSI
;
751 static void xics_register_types(void)
753 type_register_static(&xics_common_info
);
754 type_register_static(&ics_simple_info
);
755 type_register_static(&ics_base_info
);
756 type_register_static(&icp_info
);
759 type_init(xics_register_types
)