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 xics_common_pic_print_info(InterruptStatsProvider
*obj
,
98 XICSState
*xics
= XICS_COMMON(obj
);
102 for (i
= 0; i
< xics
->nr_servers
; i
++) {
103 ICPState
*icp
= &xics
->ss
[i
];
108 monitor_printf(mon
, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n",
109 i
, icp
->xirr
, icp
->xirr_owner
,
110 icp
->pending_priority
, icp
->mfrr
);
113 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
114 monitor_printf(mon
, "ICS %4x..%4x %p\n",
115 ics
->offset
, ics
->offset
+ ics
->nr_irqs
- 1, ics
);
121 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
122 ICSIRQState
*irq
= ics
->irqs
+ i
;
124 if (!(irq
->flags
& XICS_FLAGS_IRQ_MASK
)) {
127 monitor_printf(mon
, " %4x %s %02x %02x\n",
129 (irq
->flags
& XICS_FLAGS_IRQ_LSI
) ?
131 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_prop_get_nr_irqs(Object
*obj
, Visitor
*v
, const char *name
,
155 void *opaque
, Error
**errp
)
157 XICSState
*xics
= XICS_COMMON(obj
);
158 int64_t value
= xics
->nr_irqs
;
160 visit_type_int(v
, name
, &value
, errp
);
163 static void xics_prop_set_nr_irqs(Object
*obj
, Visitor
*v
, const char *name
,
164 void *opaque
, Error
**errp
)
166 XICSState
*xics
= XICS_COMMON(obj
);
167 XICSStateClass
*info
= XICS_COMMON_GET_CLASS(xics
);
171 visit_type_int(v
, name
, &value
, &error
);
173 error_propagate(errp
, error
);
177 error_setg(errp
, "Number of interrupts is already set to %u",
182 assert(info
->set_nr_irqs
);
183 info
->set_nr_irqs(xics
, value
, errp
);
186 void xics_set_nr_servers(XICSState
*xics
, uint32_t nr_servers
,
187 const char *typename
, Error
**errp
)
191 xics
->nr_servers
= nr_servers
;
193 xics
->ss
= g_malloc0(xics
->nr_servers
* sizeof(ICPState
));
194 for (i
= 0; i
< xics
->nr_servers
; i
++) {
196 ICPState
*icp
= &xics
->ss
[i
];
198 object_initialize(icp
, sizeof(*icp
), typename
);
199 snprintf(name
, sizeof(name
), "icp[%d]", i
);
200 object_property_add_child(OBJECT(xics
), name
, OBJECT(icp
), errp
);
205 static void xics_prop_get_nr_servers(Object
*obj
, Visitor
*v
,
206 const char *name
, void *opaque
,
209 XICSState
*xics
= XICS_COMMON(obj
);
210 int64_t value
= xics
->nr_servers
;
212 visit_type_int(v
, name
, &value
, errp
);
215 static void xics_prop_set_nr_servers(Object
*obj
, Visitor
*v
,
216 const char *name
, void *opaque
,
219 XICSState
*xics
= XICS_COMMON(obj
);
220 XICSStateClass
*xsc
= XICS_COMMON_GET_CLASS(xics
);
224 visit_type_int(v
, name
, &value
, &error
);
226 error_propagate(errp
, error
);
229 if (xics
->nr_servers
) {
230 error_setg(errp
, "Number of servers is already set to %u",
235 assert(xsc
->set_nr_servers
);
236 xsc
->set_nr_servers(xics
, value
, errp
);
239 static void xics_common_initfn(Object
*obj
)
241 XICSState
*xics
= XICS_COMMON(obj
);
243 QLIST_INIT(&xics
->ics
);
244 object_property_add(obj
, "nr_irqs", "int",
245 xics_prop_get_nr_irqs
, xics_prop_set_nr_irqs
,
247 object_property_add(obj
, "nr_servers", "int",
248 xics_prop_get_nr_servers
, xics_prop_set_nr_servers
,
252 static void xics_common_class_init(ObjectClass
*oc
, void *data
)
254 DeviceClass
*dc
= DEVICE_CLASS(oc
);
255 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(oc
);
257 dc
->reset
= xics_common_reset
;
258 ic
->print_info
= xics_common_pic_print_info
;
261 static const TypeInfo xics_common_info
= {
262 .name
= TYPE_XICS_COMMON
,
263 .parent
= TYPE_SYS_BUS_DEVICE
,
264 .instance_size
= sizeof(XICSState
),
265 .class_size
= sizeof(XICSStateClass
),
266 .instance_init
= xics_common_initfn
,
267 .class_init
= xics_common_class_init
,
268 .interfaces
= (InterfaceInfo
[]) {
269 { TYPE_INTERRUPT_STATS_PROVIDER
},
275 * ICP: Presentation layer
278 #define XISR_MASK 0x00ffffff
279 #define CPPR_MASK 0xff000000
281 #define XISR(ss) (((ss)->xirr) & XISR_MASK)
282 #define CPPR(ss) (((ss)->xirr) >> 24)
284 static void ics_reject(ICSState
*ics
, uint32_t nr
)
286 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
293 static void ics_resend(ICSState
*ics
)
295 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
302 static void ics_eoi(ICSState
*ics
, int nr
)
304 ICSStateClass
*k
= ICS_BASE_GET_CLASS(ics
);
311 static void icp_check_ipi(ICPState
*ss
)
313 if (XISR(ss
) && (ss
->pending_priority
<= ss
->mfrr
)) {
317 trace_xics_icp_check_ipi(ss
->cs
->cpu_index
, ss
->mfrr
);
319 if (XISR(ss
) && ss
->xirr_owner
) {
320 ics_reject(ss
->xirr_owner
, XISR(ss
));
323 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | XICS_IPI
;
324 ss
->pending_priority
= ss
->mfrr
;
325 ss
->xirr_owner
= NULL
;
326 qemu_irq_raise(ss
->output
);
329 static void icp_resend(ICPState
*ss
)
333 if (ss
->mfrr
< CPPR(ss
)) {
336 QLIST_FOREACH(ics
, &ss
->xics
->ics
, list
) {
341 void icp_set_cppr(ICPState
*ss
, uint8_t cppr
)
347 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (cppr
<< 24);
349 if (cppr
< old_cppr
) {
350 if (XISR(ss
) && (cppr
<= ss
->pending_priority
)) {
352 ss
->xirr
&= ~XISR_MASK
; /* Clear XISR */
353 ss
->pending_priority
= 0xff;
354 qemu_irq_lower(ss
->output
);
355 if (ss
->xirr_owner
) {
356 ics_reject(ss
->xirr_owner
, old_xisr
);
357 ss
->xirr_owner
= NULL
;
367 void icp_set_mfrr(ICPState
*ss
, uint8_t mfrr
)
370 if (mfrr
< CPPR(ss
)) {
375 uint32_t icp_accept(ICPState
*ss
)
377 uint32_t xirr
= ss
->xirr
;
379 qemu_irq_lower(ss
->output
);
380 ss
->xirr
= ss
->pending_priority
<< 24;
381 ss
->pending_priority
= 0xff;
382 ss
->xirr_owner
= NULL
;
384 trace_xics_icp_accept(xirr
, ss
->xirr
);
389 uint32_t icp_ipoll(ICPState
*ss
, uint32_t *mfrr
)
397 void icp_eoi(ICPState
*ss
, uint32_t xirr
)
402 /* Send EOI -> ICS */
403 ss
->xirr
= (ss
->xirr
& ~CPPR_MASK
) | (xirr
& CPPR_MASK
);
404 trace_xics_icp_eoi(ss
->cs
->cpu_index
, xirr
, ss
->xirr
);
405 irq
= xirr
& XISR_MASK
;
406 QLIST_FOREACH(ics
, &ss
->xics
->ics
, list
) {
407 if (ics_valid_irq(ics
, irq
)) {
416 static void icp_irq(ICSState
*ics
, int server
, int nr
, uint8_t priority
)
418 XICSState
*xics
= ics
->xics
;
419 ICPState
*ss
= xics
->ss
+ server
;
421 trace_xics_icp_irq(server
, nr
, priority
);
423 if ((priority
>= CPPR(ss
))
424 || (XISR(ss
) && (ss
->pending_priority
<= priority
))) {
427 if (XISR(ss
) && ss
->xirr_owner
) {
428 ics_reject(ss
->xirr_owner
, XISR(ss
));
429 ss
->xirr_owner
= NULL
;
431 ss
->xirr
= (ss
->xirr
& ~XISR_MASK
) | (nr
& XISR_MASK
);
432 ss
->xirr_owner
= ics
;
433 ss
->pending_priority
= priority
;
434 trace_xics_icp_raise(ss
->xirr
, ss
->pending_priority
);
435 qemu_irq_raise(ss
->output
);
439 static void icp_dispatch_pre_save(void *opaque
)
441 ICPState
*ss
= opaque
;
442 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
444 if (info
->pre_save
) {
449 static int icp_dispatch_post_load(void *opaque
, int version_id
)
451 ICPState
*ss
= opaque
;
452 ICPStateClass
*info
= ICP_GET_CLASS(ss
);
454 if (info
->post_load
) {
455 return info
->post_load(ss
, version_id
);
461 static const VMStateDescription vmstate_icp_server
= {
462 .name
= "icp/server",
464 .minimum_version_id
= 1,
465 .pre_save
= icp_dispatch_pre_save
,
466 .post_load
= icp_dispatch_post_load
,
467 .fields
= (VMStateField
[]) {
469 VMSTATE_UINT32(xirr
, ICPState
),
470 VMSTATE_UINT8(pending_priority
, ICPState
),
471 VMSTATE_UINT8(mfrr
, ICPState
),
472 VMSTATE_END_OF_LIST()
476 static void icp_reset(DeviceState
*dev
)
478 ICPState
*icp
= ICP(dev
);
481 icp
->pending_priority
= 0xff;
484 /* Make all outputs are deasserted */
485 qemu_set_irq(icp
->output
, 0);
488 static void icp_class_init(ObjectClass
*klass
, void *data
)
490 DeviceClass
*dc
= DEVICE_CLASS(klass
);
492 dc
->reset
= icp_reset
;
493 dc
->vmsd
= &vmstate_icp_server
;
496 static const TypeInfo icp_info
= {
498 .parent
= TYPE_DEVICE
,
499 .instance_size
= sizeof(ICPState
),
500 .class_init
= icp_class_init
,
501 .class_size
= sizeof(ICPStateClass
),
507 static void ics_simple_resend_msi(ICSState
*ics
, int srcno
)
509 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
511 /* FIXME: filter by server#? */
512 if (irq
->status
& XICS_STATUS_REJECTED
) {
513 irq
->status
&= ~XICS_STATUS_REJECTED
;
514 if (irq
->priority
!= 0xff) {
515 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
520 static void ics_simple_resend_lsi(ICSState
*ics
, int srcno
)
522 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
524 if ((irq
->priority
!= 0xff)
525 && (irq
->status
& XICS_STATUS_ASSERTED
)
526 && !(irq
->status
& XICS_STATUS_SENT
)) {
527 irq
->status
|= XICS_STATUS_SENT
;
528 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
532 static void ics_simple_set_irq_msi(ICSState
*ics
, int srcno
, int val
)
534 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
536 trace_xics_ics_simple_set_irq_msi(srcno
, srcno
+ ics
->offset
);
539 if (irq
->priority
== 0xff) {
540 irq
->status
|= XICS_STATUS_MASKED_PENDING
;
541 trace_xics_masked_pending();
543 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
548 static void ics_simple_set_irq_lsi(ICSState
*ics
, int srcno
, int val
)
550 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
552 trace_xics_ics_simple_set_irq_lsi(srcno
, srcno
+ ics
->offset
);
554 irq
->status
|= XICS_STATUS_ASSERTED
;
556 irq
->status
&= ~XICS_STATUS_ASSERTED
;
558 ics_simple_resend_lsi(ics
, srcno
);
561 static void ics_simple_set_irq(void *opaque
, int srcno
, int val
)
563 ICSState
*ics
= (ICSState
*)opaque
;
565 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
566 ics_simple_set_irq_lsi(ics
, srcno
, val
);
568 ics_simple_set_irq_msi(ics
, srcno
, val
);
572 static void ics_simple_write_xive_msi(ICSState
*ics
, int srcno
)
574 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
576 if (!(irq
->status
& XICS_STATUS_MASKED_PENDING
)
577 || (irq
->priority
== 0xff)) {
581 irq
->status
&= ~XICS_STATUS_MASKED_PENDING
;
582 icp_irq(ics
, irq
->server
, srcno
+ ics
->offset
, irq
->priority
);
585 static void ics_simple_write_xive_lsi(ICSState
*ics
, int srcno
)
587 ics_simple_resend_lsi(ics
, srcno
);
590 void ics_simple_write_xive(ICSState
*ics
, int srcno
, int server
,
591 uint8_t priority
, uint8_t saved_priority
)
593 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
595 irq
->server
= server
;
596 irq
->priority
= priority
;
597 irq
->saved_priority
= saved_priority
;
599 trace_xics_ics_simple_write_xive(ics
->offset
+ srcno
, srcno
, server
,
602 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
603 ics_simple_write_xive_lsi(ics
, srcno
);
605 ics_simple_write_xive_msi(ics
, srcno
);
609 static void ics_simple_reject(ICSState
*ics
, uint32_t nr
)
611 ICSIRQState
*irq
= ics
->irqs
+ nr
- ics
->offset
;
613 trace_xics_ics_simple_reject(nr
, nr
- ics
->offset
);
614 if (irq
->flags
& XICS_FLAGS_IRQ_MSI
) {
615 irq
->status
|= XICS_STATUS_REJECTED
;
616 } else if (irq
->flags
& XICS_FLAGS_IRQ_LSI
) {
617 irq
->status
&= ~XICS_STATUS_SENT
;
621 static void ics_simple_resend(ICSState
*ics
)
625 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
626 /* FIXME: filter by server#? */
627 if (ics
->irqs
[i
].flags
& XICS_FLAGS_IRQ_LSI
) {
628 ics_simple_resend_lsi(ics
, i
);
630 ics_simple_resend_msi(ics
, i
);
635 static void ics_simple_eoi(ICSState
*ics
, uint32_t nr
)
637 int srcno
= nr
- ics
->offset
;
638 ICSIRQState
*irq
= ics
->irqs
+ srcno
;
640 trace_xics_ics_simple_eoi(nr
);
642 if (ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_LSI
) {
643 irq
->status
&= ~XICS_STATUS_SENT
;
647 static void ics_simple_reset(DeviceState
*dev
)
649 ICSState
*ics
= ICS_SIMPLE(dev
);
651 uint8_t flags
[ics
->nr_irqs
];
653 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
654 flags
[i
] = ics
->irqs
[i
].flags
;
657 memset(ics
->irqs
, 0, sizeof(ICSIRQState
) * ics
->nr_irqs
);
659 for (i
= 0; i
< ics
->nr_irqs
; i
++) {
660 ics
->irqs
[i
].priority
= 0xff;
661 ics
->irqs
[i
].saved_priority
= 0xff;
662 ics
->irqs
[i
].flags
= flags
[i
];
666 static int ics_simple_post_load(ICSState
*ics
, int version_id
)
670 for (i
= 0; i
< ics
->xics
->nr_servers
; i
++) {
671 icp_resend(&ics
->xics
->ss
[i
]);
677 static void ics_simple_dispatch_pre_save(void *opaque
)
679 ICSState
*ics
= opaque
;
680 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
682 if (info
->pre_save
) {
687 static int ics_simple_dispatch_post_load(void *opaque
, int version_id
)
689 ICSState
*ics
= opaque
;
690 ICSStateClass
*info
= ICS_BASE_GET_CLASS(ics
);
692 if (info
->post_load
) {
693 return info
->post_load(ics
, version_id
);
699 static const VMStateDescription vmstate_ics_simple_irq
= {
702 .minimum_version_id
= 1,
703 .fields
= (VMStateField
[]) {
704 VMSTATE_UINT32(server
, ICSIRQState
),
705 VMSTATE_UINT8(priority
, ICSIRQState
),
706 VMSTATE_UINT8(saved_priority
, ICSIRQState
),
707 VMSTATE_UINT8(status
, ICSIRQState
),
708 VMSTATE_UINT8(flags
, ICSIRQState
),
709 VMSTATE_END_OF_LIST()
713 static const VMStateDescription vmstate_ics_simple
= {
716 .minimum_version_id
= 1,
717 .pre_save
= ics_simple_dispatch_pre_save
,
718 .post_load
= ics_simple_dispatch_post_load
,
719 .fields
= (VMStateField
[]) {
721 VMSTATE_UINT32_EQUAL(nr_irqs
, ICSState
),
723 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs
, ICSState
, nr_irqs
,
724 vmstate_ics_simple_irq
,
726 VMSTATE_END_OF_LIST()
730 static void ics_simple_initfn(Object
*obj
)
732 ICSState
*ics
= ICS_SIMPLE(obj
);
734 ics
->offset
= XICS_IRQ_BASE
;
737 static void ics_simple_realize(DeviceState
*dev
, Error
**errp
)
739 ICSState
*ics
= ICS_SIMPLE(dev
);
742 error_setg(errp
, "Number of interrupts needs to be greater 0");
745 ics
->irqs
= g_malloc0(ics
->nr_irqs
* sizeof(ICSIRQState
));
746 ics
->qirqs
= qemu_allocate_irqs(ics_simple_set_irq
, ics
, ics
->nr_irqs
);
749 static void ics_simple_class_init(ObjectClass
*klass
, void *data
)
751 DeviceClass
*dc
= DEVICE_CLASS(klass
);
752 ICSStateClass
*isc
= ICS_BASE_CLASS(klass
);
754 dc
->realize
= ics_simple_realize
;
755 dc
->vmsd
= &vmstate_ics_simple
;
756 dc
->reset
= ics_simple_reset
;
757 isc
->post_load
= ics_simple_post_load
;
758 isc
->reject
= ics_simple_reject
;
759 isc
->resend
= ics_simple_resend
;
760 isc
->eoi
= ics_simple_eoi
;
763 static const TypeInfo ics_simple_info
= {
764 .name
= TYPE_ICS_SIMPLE
,
765 .parent
= TYPE_ICS_BASE
,
766 .instance_size
= sizeof(ICSState
),
767 .class_init
= ics_simple_class_init
,
768 .class_size
= sizeof(ICSStateClass
),
769 .instance_init
= ics_simple_initfn
,
772 static const TypeInfo ics_base_info
= {
773 .name
= TYPE_ICS_BASE
,
774 .parent
= TYPE_DEVICE
,
776 .instance_size
= sizeof(ICSState
),
777 .class_size
= sizeof(ICSStateClass
),
783 ICSState
*xics_find_source(XICSState
*xics
, int irq
)
787 QLIST_FOREACH(ics
, &xics
->ics
, list
) {
788 if (ics_valid_irq(ics
, irq
)) {
795 qemu_irq
xics_get_qirq(XICSState
*xics
, int irq
)
797 ICSState
*ics
= xics_find_source(xics
, irq
);
800 return ics
->qirqs
[irq
- ics
->offset
];
806 void ics_set_irq_type(ICSState
*ics
, int srcno
, bool lsi
)
808 assert(!(ics
->irqs
[srcno
].flags
& XICS_FLAGS_IRQ_MASK
));
810 ics
->irqs
[srcno
].flags
|=
811 lsi
? XICS_FLAGS_IRQ_LSI
: XICS_FLAGS_IRQ_MSI
;
814 static void xics_register_types(void)
816 type_register_static(&xics_common_info
);
817 type_register_static(&ics_simple_info
);
818 type_register_static(&ics_base_info
);
819 type_register_static(&icp_info
);
822 type_init(xics_register_types
)