xref: /openbmc/qemu/hw/intc/xics.c (revision 5a3d7b23ba41b4884b43b6bc936ea18f999d5c6b)
1 /*
2  * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
3  *
4  * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
5  *
6  * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include "hw/hw.h"
29 #include "trace.h"
30 #include "hw/ppc/spapr.h"
31 #include "hw/ppc/xics.h"
32 #include "qemu/error-report.h"
33 #include "qapi/visitor.h"
34 
35 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
36 {
37     CPUState *cs = CPU(cpu);
38     CPUPPCState *env = &cpu->env;
39     ICPState *ss = &icp->ss[cs->cpu_index];
40 
41     assert(cs->cpu_index < icp->nr_servers);
42 
43     switch (PPC_INPUT(env)) {
44     case PPC_FLAGS_INPUT_POWER7:
45         ss->output = env->irq_inputs[POWER7_INPUT_INT];
46         break;
47 
48     case PPC_FLAGS_INPUT_970:
49         ss->output = env->irq_inputs[PPC970_INPUT_INT];
50         break;
51 
52     default:
53         error_report("XICS interrupt controller does not support this CPU "
54                      "bus model");
55         abort();
56     }
57 }
58 
59 /*
60  * XICS Common class - parent for emulated XICS and KVM-XICS
61  */
62 static void xics_common_reset(DeviceState *d)
63 {
64     XICSState *icp = XICS_COMMON(d);
65     int i;
66 
67     for (i = 0; i < icp->nr_servers; i++) {
68         device_reset(DEVICE(&icp->ss[i]));
69     }
70 
71     device_reset(DEVICE(icp->ics));
72 }
73 
74 static void xics_prop_get_nr_irqs(Object *obj, Visitor *v,
75                                   void *opaque, const char *name, Error **errp)
76 {
77     XICSState *icp = XICS_COMMON(obj);
78     int64_t value = icp->nr_irqs;
79 
80     visit_type_int(v, &value, name, errp);
81 }
82 
83 static void xics_prop_set_nr_irqs(Object *obj, Visitor *v,
84                                   void *opaque, const char *name, Error **errp)
85 {
86     XICSState *icp = XICS_COMMON(obj);
87     XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
88     Error *error = NULL;
89     int64_t value;
90 
91     visit_type_int(v, &value, name, &error);
92     if (error) {
93         error_propagate(errp, error);
94         return;
95     }
96     if (icp->nr_irqs) {
97         error_setg(errp, "Number of interrupts is already set to %u",
98                    icp->nr_irqs);
99         return;
100     }
101 
102     assert(info->set_nr_irqs);
103     assert(icp->ics);
104     info->set_nr_irqs(icp, value, errp);
105 }
106 
107 static void xics_prop_get_nr_servers(Object *obj, Visitor *v,
108                                      void *opaque, const char *name,
109                                      Error **errp)
110 {
111     XICSState *icp = XICS_COMMON(obj);
112     int64_t value = icp->nr_servers;
113 
114     visit_type_int(v, &value, name, errp);
115 }
116 
117 static void xics_prop_set_nr_servers(Object *obj, Visitor *v,
118                                      void *opaque, const char *name,
119                                      Error **errp)
120 {
121     XICSState *icp = XICS_COMMON(obj);
122     XICSStateClass *info = XICS_COMMON_GET_CLASS(icp);
123     Error *error = NULL;
124     int64_t value;
125 
126     visit_type_int(v, &value, name, &error);
127     if (error) {
128         error_propagate(errp, error);
129         return;
130     }
131     if (icp->nr_servers) {
132         error_setg(errp, "Number of servers is already set to %u",
133                    icp->nr_servers);
134         return;
135     }
136 
137     assert(info->set_nr_servers);
138     info->set_nr_servers(icp, value, errp);
139 }
140 
141 static void xics_common_initfn(Object *obj)
142 {
143     object_property_add(obj, "nr_irqs", "int",
144                         xics_prop_get_nr_irqs, xics_prop_set_nr_irqs,
145                         NULL, NULL, NULL);
146     object_property_add(obj, "nr_servers", "int",
147                         xics_prop_get_nr_servers, xics_prop_set_nr_servers,
148                         NULL, NULL, NULL);
149 }
150 
151 static void xics_common_class_init(ObjectClass *oc, void *data)
152 {
153     DeviceClass *dc = DEVICE_CLASS(oc);
154 
155     dc->reset = xics_common_reset;
156 }
157 
158 static const TypeInfo xics_common_info = {
159     .name          = TYPE_XICS_COMMON,
160     .parent        = TYPE_SYS_BUS_DEVICE,
161     .instance_size = sizeof(XICSState),
162     .class_size    = sizeof(XICSStateClass),
163     .instance_init = xics_common_initfn,
164     .class_init    = xics_common_class_init,
165 };
166 
167 /*
168  * ICP: Presentation layer
169  */
170 
171 #define XISR_MASK  0x00ffffff
172 #define CPPR_MASK  0xff000000
173 
174 #define XISR(ss)   (((ss)->xirr) & XISR_MASK)
175 #define CPPR(ss)   (((ss)->xirr) >> 24)
176 
177 static void ics_reject(ICSState *ics, int nr);
178 static void ics_resend(ICSState *ics);
179 static void ics_eoi(ICSState *ics, int nr);
180 
181 static void icp_check_ipi(XICSState *icp, int server)
182 {
183     ICPState *ss = icp->ss + server;
184 
185     if (XISR(ss) && (ss->pending_priority <= ss->mfrr)) {
186         return;
187     }
188 
189     trace_xics_icp_check_ipi(server, ss->mfrr);
190 
191     if (XISR(ss)) {
192         ics_reject(icp->ics, XISR(ss));
193     }
194 
195     ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
196     ss->pending_priority = ss->mfrr;
197     qemu_irq_raise(ss->output);
198 }
199 
200 static void icp_resend(XICSState *icp, int server)
201 {
202     ICPState *ss = icp->ss + server;
203 
204     if (ss->mfrr < CPPR(ss)) {
205         icp_check_ipi(icp, server);
206     }
207     ics_resend(icp->ics);
208 }
209 
210 static void icp_set_cppr(XICSState *icp, int server, uint8_t cppr)
211 {
212     ICPState *ss = icp->ss + server;
213     uint8_t old_cppr;
214     uint32_t old_xisr;
215 
216     old_cppr = CPPR(ss);
217     ss->xirr = (ss->xirr & ~CPPR_MASK) | (cppr << 24);
218 
219     if (cppr < old_cppr) {
220         if (XISR(ss) && (cppr <= ss->pending_priority)) {
221             old_xisr = XISR(ss);
222             ss->xirr &= ~XISR_MASK; /* Clear XISR */
223             ss->pending_priority = 0xff;
224             qemu_irq_lower(ss->output);
225             ics_reject(icp->ics, old_xisr);
226         }
227     } else {
228         if (!XISR(ss)) {
229             icp_resend(icp, server);
230         }
231     }
232 }
233 
234 static void icp_set_mfrr(XICSState *icp, int server, uint8_t mfrr)
235 {
236     ICPState *ss = icp->ss + server;
237 
238     ss->mfrr = mfrr;
239     if (mfrr < CPPR(ss)) {
240         icp_check_ipi(icp, server);
241     }
242 }
243 
244 static uint32_t icp_accept(ICPState *ss)
245 {
246     uint32_t xirr = ss->xirr;
247 
248     qemu_irq_lower(ss->output);
249     ss->xirr = ss->pending_priority << 24;
250     ss->pending_priority = 0xff;
251 
252     trace_xics_icp_accept(xirr, ss->xirr);
253 
254     return xirr;
255 }
256 
257 static void icp_eoi(XICSState *icp, int server, uint32_t xirr)
258 {
259     ICPState *ss = icp->ss + server;
260 
261     /* Send EOI -> ICS */
262     ss->xirr = (ss->xirr & ~CPPR_MASK) | (xirr & CPPR_MASK);
263     trace_xics_icp_eoi(server, xirr, ss->xirr);
264     ics_eoi(icp->ics, xirr & XISR_MASK);
265     if (!XISR(ss)) {
266         icp_resend(icp, server);
267     }
268 }
269 
270 static void icp_irq(XICSState *icp, int server, int nr, uint8_t priority)
271 {
272     ICPState *ss = icp->ss + server;
273 
274     trace_xics_icp_irq(server, nr, priority);
275 
276     if ((priority >= CPPR(ss))
277         || (XISR(ss) && (ss->pending_priority <= priority))) {
278         ics_reject(icp->ics, nr);
279     } else {
280         if (XISR(ss)) {
281             ics_reject(icp->ics, XISR(ss));
282         }
283         ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
284         ss->pending_priority = priority;
285         trace_xics_icp_raise(ss->xirr, ss->pending_priority);
286         qemu_irq_raise(ss->output);
287     }
288 }
289 
290 static void icp_dispatch_pre_save(void *opaque)
291 {
292     ICPState *ss = opaque;
293     ICPStateClass *info = ICP_GET_CLASS(ss);
294 
295     if (info->pre_save) {
296         info->pre_save(ss);
297     }
298 }
299 
300 static int icp_dispatch_post_load(void *opaque, int version_id)
301 {
302     ICPState *ss = opaque;
303     ICPStateClass *info = ICP_GET_CLASS(ss);
304 
305     if (info->post_load) {
306         return info->post_load(ss, version_id);
307     }
308 
309     return 0;
310 }
311 
312 static const VMStateDescription vmstate_icp_server = {
313     .name = "icp/server",
314     .version_id = 1,
315     .minimum_version_id = 1,
316     .minimum_version_id_old = 1,
317     .pre_save = icp_dispatch_pre_save,
318     .post_load = icp_dispatch_post_load,
319     .fields      = (VMStateField []) {
320         /* Sanity check */
321         VMSTATE_UINT32(xirr, ICPState),
322         VMSTATE_UINT8(pending_priority, ICPState),
323         VMSTATE_UINT8(mfrr, ICPState),
324         VMSTATE_END_OF_LIST()
325     },
326 };
327 
328 static void icp_reset(DeviceState *dev)
329 {
330     ICPState *icp = ICP(dev);
331 
332     icp->xirr = 0;
333     icp->pending_priority = 0xff;
334     icp->mfrr = 0xff;
335 
336     /* Make all outputs are deasserted */
337     qemu_set_irq(icp->output, 0);
338 }
339 
340 static void icp_class_init(ObjectClass *klass, void *data)
341 {
342     DeviceClass *dc = DEVICE_CLASS(klass);
343 
344     dc->reset = icp_reset;
345     dc->vmsd = &vmstate_icp_server;
346 }
347 
348 static const TypeInfo icp_info = {
349     .name = TYPE_ICP,
350     .parent = TYPE_DEVICE,
351     .instance_size = sizeof(ICPState),
352     .class_init = icp_class_init,
353     .class_size = sizeof(ICPStateClass),
354 };
355 
356 /*
357  * ICS: Source layer
358  */
359 static int ics_valid_irq(ICSState *ics, uint32_t nr)
360 {
361     return (nr >= ics->offset)
362         && (nr < (ics->offset + ics->nr_irqs));
363 }
364 
365 static void resend_msi(ICSState *ics, int srcno)
366 {
367     ICSIRQState *irq = ics->irqs + srcno;
368 
369     /* FIXME: filter by server#? */
370     if (irq->status & XICS_STATUS_REJECTED) {
371         irq->status &= ~XICS_STATUS_REJECTED;
372         if (irq->priority != 0xff) {
373             icp_irq(ics->icp, irq->server, srcno + ics->offset,
374                     irq->priority);
375         }
376     }
377 }
378 
379 static void resend_lsi(ICSState *ics, int srcno)
380 {
381     ICSIRQState *irq = ics->irqs + srcno;
382 
383     if ((irq->priority != 0xff)
384         && (irq->status & XICS_STATUS_ASSERTED)
385         && !(irq->status & XICS_STATUS_SENT)) {
386         irq->status |= XICS_STATUS_SENT;
387         icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
388     }
389 }
390 
391 static void set_irq_msi(ICSState *ics, int srcno, int val)
392 {
393     ICSIRQState *irq = ics->irqs + srcno;
394 
395     trace_xics_set_irq_msi(srcno, srcno + ics->offset);
396 
397     if (val) {
398         if (irq->priority == 0xff) {
399             irq->status |= XICS_STATUS_MASKED_PENDING;
400             trace_xics_masked_pending();
401         } else  {
402             icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
403         }
404     }
405 }
406 
407 static void set_irq_lsi(ICSState *ics, int srcno, int val)
408 {
409     ICSIRQState *irq = ics->irqs + srcno;
410 
411     trace_xics_set_irq_lsi(srcno, srcno + ics->offset);
412     if (val) {
413         irq->status |= XICS_STATUS_ASSERTED;
414     } else {
415         irq->status &= ~XICS_STATUS_ASSERTED;
416     }
417     resend_lsi(ics, srcno);
418 }
419 
420 static void ics_set_irq(void *opaque, int srcno, int val)
421 {
422     ICSState *ics = (ICSState *)opaque;
423 
424     if (ics->islsi[srcno]) {
425         set_irq_lsi(ics, srcno, val);
426     } else {
427         set_irq_msi(ics, srcno, val);
428     }
429 }
430 
431 static void write_xive_msi(ICSState *ics, int srcno)
432 {
433     ICSIRQState *irq = ics->irqs + srcno;
434 
435     if (!(irq->status & XICS_STATUS_MASKED_PENDING)
436         || (irq->priority == 0xff)) {
437         return;
438     }
439 
440     irq->status &= ~XICS_STATUS_MASKED_PENDING;
441     icp_irq(ics->icp, irq->server, srcno + ics->offset, irq->priority);
442 }
443 
444 static void write_xive_lsi(ICSState *ics, int srcno)
445 {
446     resend_lsi(ics, srcno);
447 }
448 
449 static void ics_write_xive(ICSState *ics, int nr, int server,
450                            uint8_t priority, uint8_t saved_priority)
451 {
452     int srcno = nr - ics->offset;
453     ICSIRQState *irq = ics->irqs + srcno;
454 
455     irq->server = server;
456     irq->priority = priority;
457     irq->saved_priority = saved_priority;
458 
459     trace_xics_ics_write_xive(nr, srcno, server, priority);
460 
461     if (ics->islsi[srcno]) {
462         write_xive_lsi(ics, srcno);
463     } else {
464         write_xive_msi(ics, srcno);
465     }
466 }
467 
468 static void ics_reject(ICSState *ics, int nr)
469 {
470     ICSIRQState *irq = ics->irqs + nr - ics->offset;
471 
472     trace_xics_ics_reject(nr, nr - ics->offset);
473     irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
474     irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
475 }
476 
477 static void ics_resend(ICSState *ics)
478 {
479     int i;
480 
481     for (i = 0; i < ics->nr_irqs; i++) {
482         /* FIXME: filter by server#? */
483         if (ics->islsi[i]) {
484             resend_lsi(ics, i);
485         } else {
486             resend_msi(ics, i);
487         }
488     }
489 }
490 
491 static void ics_eoi(ICSState *ics, int nr)
492 {
493     int srcno = nr - ics->offset;
494     ICSIRQState *irq = ics->irqs + srcno;
495 
496     trace_xics_ics_eoi(nr);
497 
498     if (ics->islsi[srcno]) {
499         irq->status &= ~XICS_STATUS_SENT;
500     }
501 }
502 
503 static void ics_reset(DeviceState *dev)
504 {
505     ICSState *ics = ICS(dev);
506     int i;
507 
508     memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
509     for (i = 0; i < ics->nr_irqs; i++) {
510         ics->irqs[i].priority = 0xff;
511         ics->irqs[i].saved_priority = 0xff;
512     }
513 }
514 
515 static int ics_post_load(ICSState *ics, int version_id)
516 {
517     int i;
518 
519     for (i = 0; i < ics->icp->nr_servers; i++) {
520         icp_resend(ics->icp, i);
521     }
522 
523     return 0;
524 }
525 
526 static void ics_dispatch_pre_save(void *opaque)
527 {
528     ICSState *ics = opaque;
529     ICSStateClass *info = ICS_GET_CLASS(ics);
530 
531     if (info->pre_save) {
532         info->pre_save(ics);
533     }
534 }
535 
536 static int ics_dispatch_post_load(void *opaque, int version_id)
537 {
538     ICSState *ics = opaque;
539     ICSStateClass *info = ICS_GET_CLASS(ics);
540 
541     if (info->post_load) {
542         return info->post_load(ics, version_id);
543     }
544 
545     return 0;
546 }
547 
548 static const VMStateDescription vmstate_ics_irq = {
549     .name = "ics/irq",
550     .version_id = 1,
551     .minimum_version_id = 1,
552     .minimum_version_id_old = 1,
553     .fields      = (VMStateField []) {
554         VMSTATE_UINT32(server, ICSIRQState),
555         VMSTATE_UINT8(priority, ICSIRQState),
556         VMSTATE_UINT8(saved_priority, ICSIRQState),
557         VMSTATE_UINT8(status, ICSIRQState),
558         VMSTATE_END_OF_LIST()
559     },
560 };
561 
562 static const VMStateDescription vmstate_ics = {
563     .name = "ics",
564     .version_id = 1,
565     .minimum_version_id = 1,
566     .minimum_version_id_old = 1,
567     .pre_save = ics_dispatch_pre_save,
568     .post_load = ics_dispatch_post_load,
569     .fields      = (VMStateField []) {
570         /* Sanity check */
571         VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
572 
573         VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
574                                              vmstate_ics_irq, ICSIRQState),
575         VMSTATE_END_OF_LIST()
576     },
577 };
578 
579 static void ics_initfn(Object *obj)
580 {
581     ICSState *ics = ICS(obj);
582 
583     ics->offset = XICS_IRQ_BASE;
584 }
585 
586 static void ics_realize(DeviceState *dev, Error **errp)
587 {
588     ICSState *ics = ICS(dev);
589 
590     if (!ics->nr_irqs) {
591         error_setg(errp, "Number of interrupts needs to be greater 0");
592         return;
593     }
594     ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
595     ics->islsi = g_malloc0(ics->nr_irqs * sizeof(bool));
596     ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
597 }
598 
599 static void ics_class_init(ObjectClass *klass, void *data)
600 {
601     DeviceClass *dc = DEVICE_CLASS(klass);
602     ICSStateClass *isc = ICS_CLASS(klass);
603 
604     dc->realize = ics_realize;
605     dc->vmsd = &vmstate_ics;
606     dc->reset = ics_reset;
607     isc->post_load = ics_post_load;
608 }
609 
610 static const TypeInfo ics_info = {
611     .name = TYPE_ICS,
612     .parent = TYPE_DEVICE,
613     .instance_size = sizeof(ICSState),
614     .class_init = ics_class_init,
615     .class_size = sizeof(ICSStateClass),
616     .instance_init = ics_initfn,
617 };
618 
619 /*
620  * Exported functions
621  */
622 
623 qemu_irq xics_get_qirq(XICSState *icp, int irq)
624 {
625     if (!ics_valid_irq(icp->ics, irq)) {
626         return NULL;
627     }
628 
629     return icp->ics->qirqs[irq - icp->ics->offset];
630 }
631 
632 void xics_set_irq_type(XICSState *icp, int irq, bool lsi)
633 {
634     assert(ics_valid_irq(icp->ics, irq));
635 
636     icp->ics->islsi[irq - icp->ics->offset] = lsi;
637 }
638 
639 /*
640  * Guest interfaces
641  */
642 
643 static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
644                            target_ulong opcode, target_ulong *args)
645 {
646     CPUState *cs = CPU(cpu);
647     target_ulong cppr = args[0];
648 
649     icp_set_cppr(spapr->icp, cs->cpu_index, cppr);
650     return H_SUCCESS;
651 }
652 
653 static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
654                           target_ulong opcode, target_ulong *args)
655 {
656     target_ulong server = args[0];
657     target_ulong mfrr = args[1];
658 
659     if (server >= spapr->icp->nr_servers) {
660         return H_PARAMETER;
661     }
662 
663     icp_set_mfrr(spapr->icp, server, mfrr);
664     return H_SUCCESS;
665 }
666 
667 static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
668                            target_ulong opcode, target_ulong *args)
669 {
670     CPUState *cs = CPU(cpu);
671     uint32_t xirr = icp_accept(spapr->icp->ss + cs->cpu_index);
672 
673     args[0] = xirr;
674     return H_SUCCESS;
675 }
676 
677 static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
678                           target_ulong opcode, target_ulong *args)
679 {
680     CPUState *cs = CPU(cpu);
681     target_ulong xirr = args[0];
682 
683     icp_eoi(spapr->icp, cs->cpu_index, xirr);
684     return H_SUCCESS;
685 }
686 
687 static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
688                           uint32_t token,
689                           uint32_t nargs, target_ulong args,
690                           uint32_t nret, target_ulong rets)
691 {
692     ICSState *ics = spapr->icp->ics;
693     uint32_t nr, server, priority;
694 
695     if ((nargs != 3) || (nret != 1)) {
696         rtas_st(rets, 0, -3);
697         return;
698     }
699 
700     nr = rtas_ld(args, 0);
701     server = rtas_ld(args, 1);
702     priority = rtas_ld(args, 2);
703 
704     if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
705         || (priority > 0xff)) {
706         rtas_st(rets, 0, -3);
707         return;
708     }
709 
710     ics_write_xive(ics, nr, server, priority, priority);
711 
712     rtas_st(rets, 0, 0); /* Success */
713 }
714 
715 static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
716                           uint32_t token,
717                           uint32_t nargs, target_ulong args,
718                           uint32_t nret, target_ulong rets)
719 {
720     ICSState *ics = spapr->icp->ics;
721     uint32_t nr;
722 
723     if ((nargs != 1) || (nret != 3)) {
724         rtas_st(rets, 0, -3);
725         return;
726     }
727 
728     nr = rtas_ld(args, 0);
729 
730     if (!ics_valid_irq(ics, nr)) {
731         rtas_st(rets, 0, -3);
732         return;
733     }
734 
735     rtas_st(rets, 0, 0); /* Success */
736     rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
737     rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
738 }
739 
740 static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
741                          uint32_t token,
742                          uint32_t nargs, target_ulong args,
743                          uint32_t nret, target_ulong rets)
744 {
745     ICSState *ics = spapr->icp->ics;
746     uint32_t nr;
747 
748     if ((nargs != 1) || (nret != 1)) {
749         rtas_st(rets, 0, -3);
750         return;
751     }
752 
753     nr = rtas_ld(args, 0);
754 
755     if (!ics_valid_irq(ics, nr)) {
756         rtas_st(rets, 0, -3);
757         return;
758     }
759 
760     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
761                    ics->irqs[nr - ics->offset].priority);
762 
763     rtas_st(rets, 0, 0); /* Success */
764 }
765 
766 static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr,
767                         uint32_t token,
768                         uint32_t nargs, target_ulong args,
769                         uint32_t nret, target_ulong rets)
770 {
771     ICSState *ics = spapr->icp->ics;
772     uint32_t nr;
773 
774     if ((nargs != 1) || (nret != 1)) {
775         rtas_st(rets, 0, -3);
776         return;
777     }
778 
779     nr = rtas_ld(args, 0);
780 
781     if (!ics_valid_irq(ics, nr)) {
782         rtas_st(rets, 0, -3);
783         return;
784     }
785 
786     ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
787                    ics->irqs[nr - ics->offset].saved_priority,
788                    ics->irqs[nr - ics->offset].saved_priority);
789 
790     rtas_st(rets, 0, 0); /* Success */
791 }
792 
793 /*
794  * XICS
795  */
796 
797 static void xics_set_nr_irqs(XICSState *icp, uint32_t nr_irqs, Error **errp)
798 {
799     icp->nr_irqs = icp->ics->nr_irqs = nr_irqs;
800 }
801 
802 static void xics_set_nr_servers(XICSState *icp, uint32_t nr_servers,
803                                 Error **errp)
804 {
805     int i;
806 
807     icp->nr_servers = nr_servers;
808 
809     icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
810     for (i = 0; i < icp->nr_servers; i++) {
811         char buffer[32];
812         object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
813         snprintf(buffer, sizeof(buffer), "icp[%d]", i);
814         object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]),
815                                   errp);
816     }
817 }
818 
819 static void xics_realize(DeviceState *dev, Error **errp)
820 {
821     XICSState *icp = XICS(dev);
822     Error *error = NULL;
823     int i;
824 
825     if (!icp->nr_servers) {
826         error_setg(errp, "Number of servers needs to be greater 0");
827         return;
828     }
829 
830     /* Registration of global state belongs into realize */
831     spapr_rtas_register("ibm,set-xive", rtas_set_xive);
832     spapr_rtas_register("ibm,get-xive", rtas_get_xive);
833     spapr_rtas_register("ibm,int-off", rtas_int_off);
834     spapr_rtas_register("ibm,int-on", rtas_int_on);
835 
836     spapr_register_hypercall(H_CPPR, h_cppr);
837     spapr_register_hypercall(H_IPI, h_ipi);
838     spapr_register_hypercall(H_XIRR, h_xirr);
839     spapr_register_hypercall(H_EOI, h_eoi);
840 
841     object_property_set_bool(OBJECT(icp->ics), true, "realized", &error);
842     if (error) {
843         error_propagate(errp, error);
844         return;
845     }
846 
847     for (i = 0; i < icp->nr_servers; i++) {
848         object_property_set_bool(OBJECT(&icp->ss[i]), true, "realized", &error);
849         if (error) {
850             error_propagate(errp, error);
851             return;
852         }
853     }
854 }
855 
856 static void xics_initfn(Object *obj)
857 {
858     XICSState *xics = XICS(obj);
859 
860     xics->ics = ICS(object_new(TYPE_ICS));
861     object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
862     xics->ics->icp = xics;
863 }
864 
865 static void xics_class_init(ObjectClass *oc, void *data)
866 {
867     DeviceClass *dc = DEVICE_CLASS(oc);
868     XICSStateClass *xsc = XICS_CLASS(oc);
869 
870     dc->realize = xics_realize;
871     xsc->set_nr_irqs = xics_set_nr_irqs;
872     xsc->set_nr_servers = xics_set_nr_servers;
873 }
874 
875 static const TypeInfo xics_info = {
876     .name          = TYPE_XICS,
877     .parent        = TYPE_XICS_COMMON,
878     .instance_size = sizeof(XICSState),
879     .class_size = sizeof(XICSStateClass),
880     .class_init    = xics_class_init,
881     .instance_init = xics_initfn,
882 };
883 
884 static void xics_register_types(void)
885 {
886     type_register_static(&xics_common_info);
887     type_register_static(&xics_info);
888     type_register_static(&ics_info);
889     type_register_static(&icp_info);
890 }
891 
892 type_init(xics_register_types)
893