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