1
2
3
4
5
6
7
8
9
10#include "qemu/osdep.h"
11#include "qemu/log.h"
12#include "qemu/module.h"
13#include "qapi/error.h"
14#include "qemu/error-report.h"
15#include "target/ppc/cpu.h"
16#include "sysemu/cpus.h"
17#include "sysemu/reset.h"
18#include "migration/vmstate.h"
19#include "monitor/monitor.h"
20#include "hw/ppc/fdt.h"
21#include "hw/ppc/spapr.h"
22#include "hw/ppc/spapr_cpu_core.h"
23#include "hw/ppc/spapr_xive.h"
24#include "hw/ppc/xive.h"
25#include "hw/ppc/xive_regs.h"
26#include "hw/qdev-properties.h"
27
28
29
30
31
32#define SPAPR_XIVE_VC_BASE 0x0006010000000000ull
33#define SPAPR_XIVE_TM_BASE 0x0006030203180000ull
34
35
36
37
38
39
40
41
42
43
44
45#define SPAPR_XIVE_NVT_BASE 0x400
46
47
48
49
50static uint32_t spapr_xive_nvt_to_target(uint8_t nvt_blk, uint32_t nvt_idx)
51{
52 return nvt_idx - SPAPR_XIVE_NVT_BASE;
53}
54
55static void spapr_xive_cpu_to_nvt(PowerPCCPU *cpu,
56 uint8_t *out_nvt_blk, uint32_t *out_nvt_idx)
57{
58 assert(cpu);
59
60 if (out_nvt_blk) {
61 *out_nvt_blk = SPAPR_XIVE_BLOCK_ID;
62 }
63
64 if (out_nvt_blk) {
65 *out_nvt_idx = SPAPR_XIVE_NVT_BASE + cpu->vcpu_id;
66 }
67}
68
69static int spapr_xive_target_to_nvt(uint32_t target,
70 uint8_t *out_nvt_blk, uint32_t *out_nvt_idx)
71{
72 PowerPCCPU *cpu = spapr_find_cpu(target);
73
74 if (!cpu) {
75 return -1;
76 }
77
78 spapr_xive_cpu_to_nvt(cpu, out_nvt_blk, out_nvt_idx);
79 return 0;
80}
81
82
83
84
85
86int spapr_xive_end_to_target(uint8_t end_blk, uint32_t end_idx,
87 uint32_t *out_server, uint8_t *out_prio)
88{
89
90 assert(end_blk == SPAPR_XIVE_BLOCK_ID);
91
92 if (out_server) {
93 *out_server = end_idx >> 3;
94 }
95
96 if (out_prio) {
97 *out_prio = end_idx & 0x7;
98 }
99 return 0;
100}
101
102static void spapr_xive_cpu_to_end(PowerPCCPU *cpu, uint8_t prio,
103 uint8_t *out_end_blk, uint32_t *out_end_idx)
104{
105 assert(cpu);
106
107 if (out_end_blk) {
108 *out_end_blk = SPAPR_XIVE_BLOCK_ID;
109 }
110
111 if (out_end_idx) {
112 *out_end_idx = (cpu->vcpu_id << 3) + prio;
113 }
114}
115
116static int spapr_xive_target_to_end(uint32_t target, uint8_t prio,
117 uint8_t *out_end_blk, uint32_t *out_end_idx)
118{
119 PowerPCCPU *cpu = spapr_find_cpu(target);
120
121 if (!cpu) {
122 return -1;
123 }
124
125 spapr_xive_cpu_to_end(cpu, prio, out_end_blk, out_end_idx);
126 return 0;
127}
128
129
130
131
132
133static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end,
134 Monitor *mon)
135{
136 uint64_t qaddr_base = xive_end_qaddr(end);
137 uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
138 uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
139 uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
140 uint32_t qentries = 1 << (qsize + 10);
141 uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6);
142 uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
143
144 monitor_printf(mon, "%3d/%d % 6d/%5d @%"PRIx64" ^%d",
145 spapr_xive_nvt_to_target(0, nvt),
146 priority, qindex, qentries, qaddr_base, qgen);
147
148 xive_end_queue_pic_print_info(end, 6, mon);
149}
150
151void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon)
152{
153 XiveSource *xsrc = &xive->source;
154 int i;
155
156 if (kvm_irqchip_in_kernel()) {
157 Error *local_err = NULL;
158
159 kvmppc_xive_synchronize_state(xive, &local_err);
160 if (local_err) {
161 error_report_err(local_err);
162 return;
163 }
164 }
165
166 monitor_printf(mon, " LISN PQ EISN CPU/PRIO EQ\n");
167
168 for (i = 0; i < xive->nr_irqs; i++) {
169 uint8_t pq = xive_source_esb_get(xsrc, i);
170 XiveEAS *eas = &xive->eat[i];
171
172 if (!xive_eas_is_valid(eas)) {
173 continue;
174 }
175
176 monitor_printf(mon, " %08x %s %c%c%c %s %08x ", i,
177 xive_source_irq_is_lsi(xsrc, i) ? "LSI" : "MSI",
178 pq & XIVE_ESB_VAL_P ? 'P' : '-',
179 pq & XIVE_ESB_VAL_Q ? 'Q' : '-',
180 xsrc->status[i] & XIVE_STATUS_ASSERTED ? 'A' : ' ',
181 xive_eas_is_masked(eas) ? "M" : " ",
182 (int) xive_get_field64(EAS_END_DATA, eas->w));
183
184 if (!xive_eas_is_masked(eas)) {
185 uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w);
186 XiveEND *end;
187
188 assert(end_idx < xive->nr_ends);
189 end = &xive->endt[end_idx];
190
191 if (xive_end_is_valid(end)) {
192 spapr_xive_end_pic_print_info(xive, end, mon);
193 }
194 }
195 monitor_printf(mon, "\n");
196 }
197}
198
199void spapr_xive_mmio_set_enabled(SpaprXive *xive, bool enable)
200{
201 memory_region_set_enabled(&xive->source.esb_mmio, enable);
202 memory_region_set_enabled(&xive->tm_mmio, enable);
203
204
205 memory_region_set_enabled(&xive->end_source.esb_mmio, false);
206}
207
208static void spapr_xive_tm_write(void *opaque, hwaddr offset,
209 uint64_t value, unsigned size)
210{
211 XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
212
213 xive_tctx_tm_write(XIVE_PRESENTER(opaque), tctx, offset, value, size);
214}
215
216static uint64_t spapr_xive_tm_read(void *opaque, hwaddr offset, unsigned size)
217{
218 XiveTCTX *tctx = spapr_cpu_state(POWERPC_CPU(current_cpu))->tctx;
219
220 return xive_tctx_tm_read(XIVE_PRESENTER(opaque), tctx, offset, size);
221}
222
223const MemoryRegionOps spapr_xive_tm_ops = {
224 .read = spapr_xive_tm_read,
225 .write = spapr_xive_tm_write,
226 .endianness = DEVICE_BIG_ENDIAN,
227 .valid = {
228 .min_access_size = 1,
229 .max_access_size = 8,
230 },
231 .impl = {
232 .min_access_size = 1,
233 .max_access_size = 8,
234 },
235};
236
237static void spapr_xive_end_reset(XiveEND *end)
238{
239 memset(end, 0, sizeof(*end));
240
241
242 end->w1 = cpu_to_be32(END_W1_ESe_Q | END_W1_ESn_Q);
243}
244
245static void spapr_xive_reset(void *dev)
246{
247 SpaprXive *xive = SPAPR_XIVE(dev);
248 int i;
249
250
251
252
253
254
255
256 for (i = 0; i < xive->nr_irqs; i++) {
257 XiveEAS *eas = &xive->eat[i];
258 if (xive_eas_is_valid(eas)) {
259 eas->w = cpu_to_be64(EAS_VALID | EAS_MASKED);
260 } else {
261 eas->w = 0;
262 }
263 }
264
265
266 for (i = 0; i < xive->nr_ends; i++) {
267 spapr_xive_end_reset(&xive->endt[i]);
268 }
269}
270
271static void spapr_xive_instance_init(Object *obj)
272{
273 SpaprXive *xive = SPAPR_XIVE(obj);
274
275 object_initialize_child(obj, "source", &xive->source, sizeof(xive->source),
276 TYPE_XIVE_SOURCE, &error_abort, NULL);
277
278 object_initialize_child(obj, "end_source", &xive->end_source,
279 sizeof(xive->end_source), TYPE_XIVE_END_SOURCE,
280 &error_abort, NULL);
281
282
283 xive->fd = -1;
284}
285
286static void spapr_xive_realize(DeviceState *dev, Error **errp)
287{
288 SpaprXive *xive = SPAPR_XIVE(dev);
289 SpaprXiveClass *sxc = SPAPR_XIVE_GET_CLASS(xive);
290 XiveSource *xsrc = &xive->source;
291 XiveENDSource *end_xsrc = &xive->end_source;
292 Error *local_err = NULL;
293
294 sxc->parent_realize(dev, &local_err);
295 if (local_err) {
296 error_propagate(errp, local_err);
297 return;
298 }
299
300 if (!xive->nr_irqs) {
301 error_setg(errp, "Number of interrupt needs to be greater 0");
302 return;
303 }
304
305 if (!xive->nr_ends) {
306 error_setg(errp, "Number of interrupt needs to be greater 0");
307 return;
308 }
309
310
311
312
313 object_property_set_int(OBJECT(xsrc), xive->nr_irqs, "nr-irqs",
314 &error_fatal);
315 object_property_set_link(OBJECT(xsrc), OBJECT(xive), "xive",
316 &error_abort);
317 object_property_set_bool(OBJECT(xsrc), true, "realized", &local_err);
318 if (local_err) {
319 error_propagate(errp, local_err);
320 return;
321 }
322 sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xsrc->esb_mmio);
323
324
325
326
327 object_property_set_int(OBJECT(end_xsrc), xive->nr_irqs, "nr-ends",
328 &error_fatal);
329 object_property_set_link(OBJECT(end_xsrc), OBJECT(xive), "xive",
330 &error_abort);
331 object_property_set_bool(OBJECT(end_xsrc), true, "realized", &local_err);
332 if (local_err) {
333 error_propagate(errp, local_err);
334 return;
335 }
336 sysbus_init_mmio(SYS_BUS_DEVICE(xive), &end_xsrc->esb_mmio);
337
338
339 xive->end_base = xive->vc_base + (1ull << xsrc->esb_shift) * xsrc->nr_irqs;
340
341
342
343
344 xive->eat = g_new0(XiveEAS, xive->nr_irqs);
345 xive->endt = g_new0(XiveEND, xive->nr_ends);
346
347 xive->nodename = g_strdup_printf("interrupt-controller@%" PRIx64,
348 xive->tm_base + XIVE_TM_USER_PAGE * (1 << TM_SHIFT));
349
350 qemu_register_reset(spapr_xive_reset, dev);
351
352
353 memory_region_init_io(&xive->tm_mmio, OBJECT(xive), &spapr_xive_tm_ops,
354 xive, "xive.tima", 4ull << TM_SHIFT);
355 sysbus_init_mmio(SYS_BUS_DEVICE(xive), &xive->tm_mmio);
356
357
358
359
360
361 sysbus_mmio_map(SYS_BUS_DEVICE(xive), 0, xive->vc_base);
362 sysbus_mmio_map(SYS_BUS_DEVICE(xive), 1, xive->end_base);
363 sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
364}
365
366static int spapr_xive_get_eas(XiveRouter *xrtr, uint8_t eas_blk,
367 uint32_t eas_idx, XiveEAS *eas)
368{
369 SpaprXive *xive = SPAPR_XIVE(xrtr);
370
371 if (eas_idx >= xive->nr_irqs) {
372 return -1;
373 }
374
375 *eas = xive->eat[eas_idx];
376 return 0;
377}
378
379static int spapr_xive_get_end(XiveRouter *xrtr,
380 uint8_t end_blk, uint32_t end_idx, XiveEND *end)
381{
382 SpaprXive *xive = SPAPR_XIVE(xrtr);
383
384 if (end_idx >= xive->nr_ends) {
385 return -1;
386 }
387
388 memcpy(end, &xive->endt[end_idx], sizeof(XiveEND));
389 return 0;
390}
391
392static int spapr_xive_write_end(XiveRouter *xrtr, uint8_t end_blk,
393 uint32_t end_idx, XiveEND *end,
394 uint8_t word_number)
395{
396 SpaprXive *xive = SPAPR_XIVE(xrtr);
397
398 if (end_idx >= xive->nr_ends) {
399 return -1;
400 }
401
402 memcpy(&xive->endt[end_idx], end, sizeof(XiveEND));
403 return 0;
404}
405
406static int spapr_xive_get_nvt(XiveRouter *xrtr,
407 uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT *nvt)
408{
409 uint32_t vcpu_id = spapr_xive_nvt_to_target(nvt_blk, nvt_idx);
410 PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);
411
412 if (!cpu) {
413
414 return -1;
415 }
416
417
418
419
420
421 nvt->w0 = cpu_to_be32(NVT_W0_VALID);
422 return 0;
423}
424
425static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk,
426 uint32_t nvt_idx, XiveNVT *nvt,
427 uint8_t word_number)
428{
429
430
431
432
433
434 g_assert_not_reached();
435}
436
437static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format,
438 uint8_t nvt_blk, uint32_t nvt_idx,
439 bool cam_ignore, uint8_t priority,
440 uint32_t logic_serv, XiveTCTXMatch *match)
441{
442 CPUState *cs;
443 int count = 0;
444
445 CPU_FOREACH(cs) {
446 PowerPCCPU *cpu = POWERPC_CPU(cs);
447 XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
448 int ring;
449
450
451
452
453
454 if (!tctx) {
455 continue;
456 }
457
458
459
460
461 ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, nvt_idx,
462 cam_ignore, logic_serv);
463
464
465
466
467 if (ring != -1) {
468 if (match->tctx) {
469 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a thread "
470 "context NVT %x/%x\n", nvt_blk, nvt_idx);
471 return -1;
472 }
473
474 match->ring = ring;
475 match->tctx = tctx;
476 count++;
477 }
478 }
479
480 return count;
481}
482
483static uint8_t spapr_xive_get_block_id(XiveRouter *xrtr)
484{
485 return SPAPR_XIVE_BLOCK_ID;
486}
487
488static const VMStateDescription vmstate_spapr_xive_end = {
489 .name = TYPE_SPAPR_XIVE "/end",
490 .version_id = 1,
491 .minimum_version_id = 1,
492 .fields = (VMStateField []) {
493 VMSTATE_UINT32(w0, XiveEND),
494 VMSTATE_UINT32(w1, XiveEND),
495 VMSTATE_UINT32(w2, XiveEND),
496 VMSTATE_UINT32(w3, XiveEND),
497 VMSTATE_UINT32(w4, XiveEND),
498 VMSTATE_UINT32(w5, XiveEND),
499 VMSTATE_UINT32(w6, XiveEND),
500 VMSTATE_UINT32(w7, XiveEND),
501 VMSTATE_END_OF_LIST()
502 },
503};
504
505static const VMStateDescription vmstate_spapr_xive_eas = {
506 .name = TYPE_SPAPR_XIVE "/eas",
507 .version_id = 1,
508 .minimum_version_id = 1,
509 .fields = (VMStateField []) {
510 VMSTATE_UINT64(w, XiveEAS),
511 VMSTATE_END_OF_LIST()
512 },
513};
514
515static int vmstate_spapr_xive_pre_save(void *opaque)
516{
517 if (kvm_irqchip_in_kernel()) {
518 return kvmppc_xive_pre_save(SPAPR_XIVE(opaque));
519 }
520
521 return 0;
522}
523
524
525
526
527
528static int spapr_xive_post_load(SpaprInterruptController *intc, int version_id)
529{
530 if (kvm_irqchip_in_kernel()) {
531 return kvmppc_xive_post_load(SPAPR_XIVE(intc), version_id);
532 }
533
534 return 0;
535}
536
537static const VMStateDescription vmstate_spapr_xive = {
538 .name = TYPE_SPAPR_XIVE,
539 .version_id = 1,
540 .minimum_version_id = 1,
541 .pre_save = vmstate_spapr_xive_pre_save,
542 .post_load = NULL,
543 .fields = (VMStateField[]) {
544 VMSTATE_UINT32_EQUAL(nr_irqs, SpaprXive, NULL),
545 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(eat, SpaprXive, nr_irqs,
546 vmstate_spapr_xive_eas, XiveEAS),
547 VMSTATE_STRUCT_VARRAY_POINTER_UINT32(endt, SpaprXive, nr_ends,
548 vmstate_spapr_xive_end, XiveEND),
549 VMSTATE_END_OF_LIST()
550 },
551};
552
553static int spapr_xive_claim_irq(SpaprInterruptController *intc, int lisn,
554 bool lsi, Error **errp)
555{
556 SpaprXive *xive = SPAPR_XIVE(intc);
557 XiveSource *xsrc = &xive->source;
558
559 assert(lisn < xive->nr_irqs);
560
561 if (xive_eas_is_valid(&xive->eat[lisn])) {
562 error_setg(errp, "IRQ %d is not free", lisn);
563 return -EBUSY;
564 }
565
566
567
568
569 xive->eat[lisn].w |= cpu_to_be64(EAS_VALID | EAS_MASKED);
570 if (lsi) {
571 xive_source_irq_set_lsi(xsrc, lisn);
572 }
573
574 if (kvm_irqchip_in_kernel()) {
575 return kvmppc_xive_source_reset_one(xsrc, lisn, errp);
576 }
577
578 return 0;
579}
580
581static void spapr_xive_free_irq(SpaprInterruptController *intc, int lisn)
582{
583 SpaprXive *xive = SPAPR_XIVE(intc);
584 assert(lisn < xive->nr_irqs);
585
586 xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID);
587}
588
589static Property spapr_xive_properties[] = {
590 DEFINE_PROP_UINT32("nr-irqs", SpaprXive, nr_irqs, 0),
591 DEFINE_PROP_UINT32("nr-ends", SpaprXive, nr_ends, 0),
592 DEFINE_PROP_UINT64("vc-base", SpaprXive, vc_base, SPAPR_XIVE_VC_BASE),
593 DEFINE_PROP_UINT64("tm-base", SpaprXive, tm_base, SPAPR_XIVE_TM_BASE),
594 DEFINE_PROP_END_OF_LIST(),
595};
596
597static int spapr_xive_cpu_intc_create(SpaprInterruptController *intc,
598 PowerPCCPU *cpu, Error **errp)
599{
600 SpaprXive *xive = SPAPR_XIVE(intc);
601 Object *obj;
602 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
603
604 obj = xive_tctx_create(OBJECT(cpu), XIVE_PRESENTER(xive), errp);
605 if (!obj) {
606 return -1;
607 }
608
609 spapr_cpu->tctx = XIVE_TCTX(obj);
610 return 0;
611}
612
613static void xive_tctx_set_os_cam(XiveTCTX *tctx, uint32_t os_cam)
614{
615 uint32_t qw1w2 = cpu_to_be32(TM_QW1W2_VO | os_cam);
616 memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4);
617}
618
619static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
620 PowerPCCPU *cpu)
621{
622 XiveTCTX *tctx = spapr_cpu_state(cpu)->tctx;
623 uint8_t nvt_blk;
624 uint32_t nvt_idx;
625
626 xive_tctx_reset(tctx);
627
628
629
630
631
632
633 spapr_xive_cpu_to_nvt(cpu, &nvt_blk, &nvt_idx);
634
635 xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
636}
637
638static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc,
639 PowerPCCPU *cpu)
640{
641 SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
642
643 xive_tctx_destroy(spapr_cpu->tctx);
644 spapr_cpu->tctx = NULL;
645}
646
647static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
648{
649 SpaprXive *xive = SPAPR_XIVE(intc);
650
651 if (kvm_irqchip_in_kernel()) {
652 kvmppc_xive_source_set_irq(&xive->source, irq, val);
653 } else {
654 xive_source_set_irq(&xive->source, irq, val);
655 }
656}
657
658static void spapr_xive_print_info(SpaprInterruptController *intc, Monitor *mon)
659{
660 SpaprXive *xive = SPAPR_XIVE(intc);
661 CPUState *cs;
662
663 CPU_FOREACH(cs) {
664 PowerPCCPU *cpu = POWERPC_CPU(cs);
665
666 xive_tctx_pic_print_info(spapr_cpu_state(cpu)->tctx, mon);
667 }
668
669 spapr_xive_pic_print_info(xive, mon);
670}
671
672static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers,
673 void *fdt, uint32_t phandle)
674{
675 SpaprXive *xive = SPAPR_XIVE(intc);
676 int node;
677 uint64_t timas[2 * 2];
678
679 uint32_t lisn_ranges[] = {
680 cpu_to_be32(SPAPR_IRQ_IPI),
681 cpu_to_be32(SPAPR_IRQ_IPI + nr_servers),
682 };
683
684
685
686
687 uint32_t eq_sizes[] = {
688 cpu_to_be32(16),
689 };
690
691
692
693
694 uint32_t plat_res_int_priorities[] = {
695 cpu_to_be32(7),
696 cpu_to_be32(0xf8),
697 };
698
699
700 timas[0] = cpu_to_be64(xive->tm_base +
701 XIVE_TM_USER_PAGE * (1ull << TM_SHIFT));
702 timas[1] = cpu_to_be64(1ull << TM_SHIFT);
703 timas[2] = cpu_to_be64(xive->tm_base +
704 XIVE_TM_OS_PAGE * (1ull << TM_SHIFT));
705 timas[3] = cpu_to_be64(1ull << TM_SHIFT);
706
707 _FDT(node = fdt_add_subnode(fdt, 0, xive->nodename));
708
709 _FDT(fdt_setprop_string(fdt, node, "device_type", "power-ivpe"));
710 _FDT(fdt_setprop(fdt, node, "reg", timas, sizeof(timas)));
711
712 _FDT(fdt_setprop_string(fdt, node, "compatible", "ibm,power-ivpe"));
713 _FDT(fdt_setprop(fdt, node, "ibm,xive-eq-sizes", eq_sizes,
714 sizeof(eq_sizes)));
715 _FDT(fdt_setprop(fdt, node, "ibm,xive-lisn-ranges", lisn_ranges,
716 sizeof(lisn_ranges)));
717
718
719 _FDT(fdt_setprop(fdt, node, "interrupt-controller", NULL, 0));
720 _FDT(fdt_setprop_cell(fdt, node, "#interrupt-cells", 2));
721
722
723 _FDT(fdt_setprop_cell(fdt, node, "linux,phandle", phandle));
724 _FDT(fdt_setprop_cell(fdt, node, "phandle", phandle));
725
726
727
728
729
730 _FDT(fdt_setprop(fdt, 0, "ibm,plat-res-int-priorities",
731 plat_res_int_priorities, sizeof(plat_res_int_priorities)));
732}
733
734static int spapr_xive_activate(SpaprInterruptController *intc,
735 uint32_t nr_servers, Error **errp)
736{
737 SpaprXive *xive = SPAPR_XIVE(intc);
738
739 if (kvm_enabled()) {
740 int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, nr_servers,
741 errp);
742 if (rc < 0) {
743 return rc;
744 }
745 }
746
747
748 spapr_xive_mmio_set_enabled(xive, true);
749
750 return 0;
751}
752
753static void spapr_xive_deactivate(SpaprInterruptController *intc)
754{
755 SpaprXive *xive = SPAPR_XIVE(intc);
756
757 spapr_xive_mmio_set_enabled(xive, false);
758
759 if (kvm_irqchip_in_kernel()) {
760 kvmppc_xive_disconnect(intc);
761 }
762}
763
764static void spapr_xive_class_init(ObjectClass *klass, void *data)
765{
766 DeviceClass *dc = DEVICE_CLASS(klass);
767 XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass);
768 SpaprInterruptControllerClass *sicc = SPAPR_INTC_CLASS(klass);
769 XivePresenterClass *xpc = XIVE_PRESENTER_CLASS(klass);
770 SpaprXiveClass *sxc = SPAPR_XIVE_CLASS(klass);
771
772 dc->desc = "sPAPR XIVE Interrupt Controller";
773 device_class_set_props(dc, spapr_xive_properties);
774 device_class_set_parent_realize(dc, spapr_xive_realize,
775 &sxc->parent_realize);
776 dc->vmsd = &vmstate_spapr_xive;
777
778 xrc->get_eas = spapr_xive_get_eas;
779 xrc->get_end = spapr_xive_get_end;
780 xrc->write_end = spapr_xive_write_end;
781 xrc->get_nvt = spapr_xive_get_nvt;
782 xrc->write_nvt = spapr_xive_write_nvt;
783 xrc->get_block_id = spapr_xive_get_block_id;
784
785 sicc->activate = spapr_xive_activate;
786 sicc->deactivate = spapr_xive_deactivate;
787 sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
788 sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
789 sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy;
790 sicc->claim_irq = spapr_xive_claim_irq;
791 sicc->free_irq = spapr_xive_free_irq;
792 sicc->set_irq = spapr_xive_set_irq;
793 sicc->print_info = spapr_xive_print_info;
794 sicc->dt = spapr_xive_dt;
795 sicc->post_load = spapr_xive_post_load;
796
797 xpc->match_nvt = spapr_xive_match_nvt;
798}
799
800static const TypeInfo spapr_xive_info = {
801 .name = TYPE_SPAPR_XIVE,
802 .parent = TYPE_XIVE_ROUTER,
803 .instance_init = spapr_xive_instance_init,
804 .instance_size = sizeof(SpaprXive),
805 .class_init = spapr_xive_class_init,
806 .class_size = sizeof(SpaprXiveClass),
807 .interfaces = (InterfaceInfo[]) {
808 { TYPE_SPAPR_INTC },
809 { }
810 },
811};
812
813static void spapr_xive_register_types(void)
814{
815 type_register_static(&spapr_xive_info);
816}
817
818type_init(spapr_xive_register_types)
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841static bool spapr_xive_priority_is_reserved(uint8_t priority)
842{
843 switch (priority) {
844 case 0 ... 6:
845 return false;
846 case 7:
847 default:
848 return true;
849 }
850}
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882#define SPAPR_XIVE_SRC_H_INT_ESB PPC_BIT(60)
883#define SPAPR_XIVE_SRC_LSI PPC_BIT(61)
884#define SPAPR_XIVE_SRC_TRIGGER PPC_BIT(62)
885
886#define SPAPR_XIVE_SRC_STORE_EOI PPC_BIT(63)
887
888static target_ulong h_int_get_source_info(PowerPCCPU *cpu,
889 SpaprMachineState *spapr,
890 target_ulong opcode,
891 target_ulong *args)
892{
893 SpaprXive *xive = spapr->xive;
894 XiveSource *xsrc = &xive->source;
895 target_ulong flags = args[0];
896 target_ulong lisn = args[1];
897
898 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
899 return H_FUNCTION;
900 }
901
902 if (flags) {
903 return H_PARAMETER;
904 }
905
906 if (lisn >= xive->nr_irqs) {
907 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
908 lisn);
909 return H_P2;
910 }
911
912 if (!xive_eas_is_valid(&xive->eat[lisn])) {
913 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
914 lisn);
915 return H_P2;
916 }
917
918
919
920
921
922 args[0] = 0;
923 if (!xive_source_esb_has_2page(xsrc)) {
924 args[0] |= SPAPR_XIVE_SRC_TRIGGER;
925 }
926 if (xsrc->esb_flags & XIVE_SRC_STORE_EOI) {
927 args[0] |= SPAPR_XIVE_SRC_STORE_EOI;
928 }
929
930
931
932
933
934
935 if (xive_source_irq_is_lsi(xsrc, lisn)) {
936 args[0] |= SPAPR_XIVE_SRC_H_INT_ESB | SPAPR_XIVE_SRC_LSI;
937 }
938
939 if (!(args[0] & SPAPR_XIVE_SRC_H_INT_ESB)) {
940 args[1] = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn);
941 } else {
942 args[1] = -1;
943 }
944
945 if (xive_source_esb_has_2page(xsrc) &&
946 !(args[0] & SPAPR_XIVE_SRC_H_INT_ESB)) {
947 args[2] = xive->vc_base + xive_source_esb_page(xsrc, lisn);
948 } else {
949 args[2] = -1;
950 }
951
952 if (xive_source_esb_has_2page(xsrc)) {
953 args[3] = xsrc->esb_shift - 1;
954 } else {
955 args[3] = xsrc->esb_shift;
956 }
957
958 return H_SUCCESS;
959}
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995#define SPAPR_XIVE_SRC_SET_EISN PPC_BIT(62)
996#define SPAPR_XIVE_SRC_MASK PPC_BIT(63)
997
998static target_ulong h_int_set_source_config(PowerPCCPU *cpu,
999 SpaprMachineState *spapr,
1000 target_ulong opcode,
1001 target_ulong *args)
1002{
1003 SpaprXive *xive = spapr->xive;
1004 XiveEAS eas, new_eas;
1005 target_ulong flags = args[0];
1006 target_ulong lisn = args[1];
1007 target_ulong target = args[2];
1008 target_ulong priority = args[3];
1009 target_ulong eisn = args[4];
1010 uint8_t end_blk;
1011 uint32_t end_idx;
1012
1013 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1014 return H_FUNCTION;
1015 }
1016
1017 if (flags & ~(SPAPR_XIVE_SRC_SET_EISN | SPAPR_XIVE_SRC_MASK)) {
1018 return H_PARAMETER;
1019 }
1020
1021 if (lisn >= xive->nr_irqs) {
1022 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
1023 lisn);
1024 return H_P2;
1025 }
1026
1027 eas = xive->eat[lisn];
1028 if (!xive_eas_is_valid(&eas)) {
1029 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
1030 lisn);
1031 return H_P2;
1032 }
1033
1034
1035 if (priority == 0xff) {
1036 new_eas.w = cpu_to_be64(EAS_VALID | EAS_MASKED);
1037 goto out;
1038 }
1039
1040 if (flags & SPAPR_XIVE_SRC_MASK) {
1041 new_eas.w = eas.w | cpu_to_be64(EAS_MASKED);
1042 } else {
1043 new_eas.w = eas.w & cpu_to_be64(~EAS_MASKED);
1044 }
1045
1046 if (spapr_xive_priority_is_reserved(priority)) {
1047 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
1048 " is reserved\n", priority);
1049 return H_P4;
1050 }
1051
1052
1053
1054
1055
1056
1057 if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
1058 return H_P3;
1059 }
1060
1061 new_eas.w = xive_set_field64(EAS_END_BLOCK, new_eas.w, end_blk);
1062 new_eas.w = xive_set_field64(EAS_END_INDEX, new_eas.w, end_idx);
1063
1064 if (flags & SPAPR_XIVE_SRC_SET_EISN) {
1065 new_eas.w = xive_set_field64(EAS_END_DATA, new_eas.w, eisn);
1066 }
1067
1068 if (kvm_irqchip_in_kernel()) {
1069 Error *local_err = NULL;
1070
1071 kvmppc_xive_set_source_config(xive, lisn, &new_eas, &local_err);
1072 if (local_err) {
1073 error_report_err(local_err);
1074 return H_HARDWARE;
1075 }
1076 }
1077
1078out:
1079 xive->eat[lisn] = new_eas;
1080 return H_SUCCESS;
1081}
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105static target_ulong h_int_get_source_config(PowerPCCPU *cpu,
1106 SpaprMachineState *spapr,
1107 target_ulong opcode,
1108 target_ulong *args)
1109{
1110 SpaprXive *xive = spapr->xive;
1111 target_ulong flags = args[0];
1112 target_ulong lisn = args[1];
1113 XiveEAS eas;
1114 XiveEND *end;
1115 uint8_t nvt_blk;
1116 uint32_t end_idx, nvt_idx;
1117
1118 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1119 return H_FUNCTION;
1120 }
1121
1122 if (flags) {
1123 return H_PARAMETER;
1124 }
1125
1126 if (lisn >= xive->nr_irqs) {
1127 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
1128 lisn);
1129 return H_P2;
1130 }
1131
1132 eas = xive->eat[lisn];
1133 if (!xive_eas_is_valid(&eas)) {
1134 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
1135 lisn);
1136 return H_P2;
1137 }
1138
1139
1140 end_idx = xive_get_field64(EAS_END_INDEX, eas.w);
1141
1142 assert(end_idx < xive->nr_ends);
1143 end = &xive->endt[end_idx];
1144
1145 nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6);
1146 nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end->w6);
1147 args[0] = spapr_xive_nvt_to_target(nvt_blk, nvt_idx);
1148
1149 if (xive_eas_is_masked(&eas)) {
1150 args[1] = 0xff;
1151 } else {
1152 args[1] = xive_get_field32(END_W7_F0_PRIORITY, end->w7);
1153 }
1154
1155 args[2] = xive_get_field64(EAS_END_DATA, eas.w);
1156
1157 return H_SUCCESS;
1158}
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178static target_ulong h_int_get_queue_info(PowerPCCPU *cpu,
1179 SpaprMachineState *spapr,
1180 target_ulong opcode,
1181 target_ulong *args)
1182{
1183 SpaprXive *xive = spapr->xive;
1184 XiveENDSource *end_xsrc = &xive->end_source;
1185 target_ulong flags = args[0];
1186 target_ulong target = args[1];
1187 target_ulong priority = args[2];
1188 XiveEND *end;
1189 uint8_t end_blk;
1190 uint32_t end_idx;
1191
1192 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1193 return H_FUNCTION;
1194 }
1195
1196 if (flags) {
1197 return H_PARAMETER;
1198 }
1199
1200
1201
1202
1203
1204
1205 if (spapr_xive_priority_is_reserved(priority)) {
1206 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
1207 " is reserved\n", priority);
1208 return H_P3;
1209 }
1210
1211
1212
1213
1214
1215
1216 if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
1217 return H_P2;
1218 }
1219
1220 assert(end_idx < xive->nr_ends);
1221 end = &xive->endt[end_idx];
1222
1223 args[0] = xive->end_base + (1ull << (end_xsrc->esb_shift + 1)) * end_idx;
1224 if (xive_end_is_enqueue(end)) {
1225 args[1] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
1226 } else {
1227 args[1] = 0;
1228 }
1229
1230 return H_SUCCESS;
1231}
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262#define SPAPR_XIVE_END_ALWAYS_NOTIFY PPC_BIT(63)
1263
1264static target_ulong h_int_set_queue_config(PowerPCCPU *cpu,
1265 SpaprMachineState *spapr,
1266 target_ulong opcode,
1267 target_ulong *args)
1268{
1269 SpaprXive *xive = spapr->xive;
1270 target_ulong flags = args[0];
1271 target_ulong target = args[1];
1272 target_ulong priority = args[2];
1273 target_ulong qpage = args[3];
1274 target_ulong qsize = args[4];
1275 XiveEND end;
1276 uint8_t end_blk, nvt_blk;
1277 uint32_t end_idx, nvt_idx;
1278
1279 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1280 return H_FUNCTION;
1281 }
1282
1283 if (flags & ~SPAPR_XIVE_END_ALWAYS_NOTIFY) {
1284 return H_PARAMETER;
1285 }
1286
1287
1288
1289
1290
1291
1292 if (spapr_xive_priority_is_reserved(priority)) {
1293 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
1294 " is reserved\n", priority);
1295 return H_P3;
1296 }
1297
1298
1299
1300
1301
1302
1303
1304 if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
1305 return H_P2;
1306 }
1307
1308 assert(end_idx < xive->nr_ends);
1309 memcpy(&end, &xive->endt[end_idx], sizeof(XiveEND));
1310
1311 switch (qsize) {
1312 case 12:
1313 case 16:
1314 case 21:
1315 case 24:
1316 if (!QEMU_IS_ALIGNED(qpage, 1ul << qsize)) {
1317 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: EQ @0x%" HWADDR_PRIx
1318 " is not naturally aligned with %" HWADDR_PRIx "\n",
1319 qpage, (hwaddr)1 << qsize);
1320 return H_P4;
1321 }
1322 end.w2 = cpu_to_be32((qpage >> 32) & 0x0fffffff);
1323 end.w3 = cpu_to_be32(qpage & 0xffffffff);
1324 end.w0 |= cpu_to_be32(END_W0_ENQUEUE);
1325 end.w0 = xive_set_field32(END_W0_QSIZE, end.w0, qsize - 12);
1326 break;
1327 case 0:
1328
1329 spapr_xive_end_reset(&end);
1330 goto out;
1331
1332 default:
1333 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid EQ size %"PRIx64"\n",
1334 qsize);
1335 return H_P5;
1336 }
1337
1338 if (qsize) {
1339 hwaddr plen = 1 << qsize;
1340 void *eq;
1341
1342
1343
1344
1345
1346 eq = address_space_map(CPU(cpu)->as, qpage, &plen, true,
1347 MEMTXATTRS_UNSPECIFIED);
1348 if (plen != 1 << qsize) {
1349 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to map EQ @0x%"
1350 HWADDR_PRIx "\n", qpage);
1351 return H_P4;
1352 }
1353 address_space_unmap(CPU(cpu)->as, eq, plen, true, plen);
1354 }
1355
1356
1357 if (spapr_xive_target_to_nvt(target, &nvt_blk, &nvt_idx)) {
1358 g_assert_not_reached();
1359 }
1360
1361
1362
1363
1364
1365 end.w6 = xive_set_field32(END_W6_NVT_BLOCK, 0ul, nvt_blk) |
1366 xive_set_field32(END_W6_NVT_INDEX, 0ul, nvt_idx);
1367 end.w7 = xive_set_field32(END_W7_F0_PRIORITY, 0ul, priority);
1368
1369 if (flags & SPAPR_XIVE_END_ALWAYS_NOTIFY) {
1370 end.w0 |= cpu_to_be32(END_W0_UCOND_NOTIFY);
1371 } else {
1372 end.w0 &= cpu_to_be32((uint32_t)~END_W0_UCOND_NOTIFY);
1373 }
1374
1375
1376
1377
1378
1379 end.w1 = cpu_to_be32(END_W1_GENERATION) |
1380 xive_set_field32(END_W1_PAGE_OFF, 0ul, 0ul);
1381 end.w0 |= cpu_to_be32(END_W0_VALID);
1382
1383
1384
1385
1386
1387
1388out:
1389 if (kvm_irqchip_in_kernel()) {
1390 Error *local_err = NULL;
1391
1392 kvmppc_xive_set_queue_config(xive, end_blk, end_idx, &end, &local_err);
1393 if (local_err) {
1394 error_report_err(local_err);
1395 return H_HARDWARE;
1396 }
1397 }
1398
1399
1400 memcpy(&xive->endt[end_idx], &end, sizeof(XiveEND));
1401 return H_SUCCESS;
1402}
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431#define SPAPR_XIVE_END_DEBUG PPC_BIT(63)
1432
1433static target_ulong h_int_get_queue_config(PowerPCCPU *cpu,
1434 SpaprMachineState *spapr,
1435 target_ulong opcode,
1436 target_ulong *args)
1437{
1438 SpaprXive *xive = spapr->xive;
1439 target_ulong flags = args[0];
1440 target_ulong target = args[1];
1441 target_ulong priority = args[2];
1442 XiveEND *end;
1443 uint8_t end_blk;
1444 uint32_t end_idx;
1445
1446 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1447 return H_FUNCTION;
1448 }
1449
1450 if (flags & ~SPAPR_XIVE_END_DEBUG) {
1451 return H_PARAMETER;
1452 }
1453
1454
1455
1456
1457
1458
1459 if (spapr_xive_priority_is_reserved(priority)) {
1460 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: priority " TARGET_FMT_ld
1461 " is reserved\n", priority);
1462 return H_P3;
1463 }
1464
1465
1466
1467
1468
1469
1470 if (spapr_xive_target_to_end(target, priority, &end_blk, &end_idx)) {
1471 return H_P2;
1472 }
1473
1474 assert(end_idx < xive->nr_ends);
1475 end = &xive->endt[end_idx];
1476
1477 args[0] = 0;
1478 if (xive_end_is_notify(end)) {
1479 args[0] |= SPAPR_XIVE_END_ALWAYS_NOTIFY;
1480 }
1481
1482 if (xive_end_is_enqueue(end)) {
1483 args[1] = xive_end_qaddr(end);
1484 args[2] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
1485 } else {
1486 args[1] = 0;
1487 args[2] = 0;
1488 }
1489
1490 if (kvm_irqchip_in_kernel()) {
1491 Error *local_err = NULL;
1492
1493 kvmppc_xive_get_queue_config(xive, end_blk, end_idx, end, &local_err);
1494 if (local_err) {
1495 error_report_err(local_err);
1496 return H_HARDWARE;
1497 }
1498 }
1499
1500
1501 if (flags & SPAPR_XIVE_END_DEBUG) {
1502
1503 args[0] |= (uint64_t)xive_get_field32(END_W1_GENERATION, end->w1) << 62;
1504
1505
1506 args[3] = xive_get_field32(END_W1_PAGE_OFF, end->w1);
1507 } else {
1508 args[3] = 0;
1509 }
1510
1511 return H_SUCCESS;
1512}
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534static target_ulong h_int_set_os_reporting_line(PowerPCCPU *cpu,
1535 SpaprMachineState *spapr,
1536 target_ulong opcode,
1537 target_ulong *args)
1538{
1539 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1540 return H_FUNCTION;
1541 }
1542
1543
1544
1545
1546
1547
1548
1549 return H_FUNCTION;
1550}
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570static target_ulong h_int_get_os_reporting_line(PowerPCCPU *cpu,
1571 SpaprMachineState *spapr,
1572 target_ulong opcode,
1573 target_ulong *args)
1574{
1575 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1576 return H_FUNCTION;
1577 }
1578
1579
1580
1581
1582
1583
1584
1585 return H_FUNCTION;
1586}
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611#define SPAPR_XIVE_ESB_STORE PPC_BIT(63)
1612
1613static target_ulong h_int_esb(PowerPCCPU *cpu,
1614 SpaprMachineState *spapr,
1615 target_ulong opcode,
1616 target_ulong *args)
1617{
1618 SpaprXive *xive = spapr->xive;
1619 XiveEAS eas;
1620 target_ulong flags = args[0];
1621 target_ulong lisn = args[1];
1622 target_ulong offset = args[2];
1623 target_ulong data = args[3];
1624 hwaddr mmio_addr;
1625 XiveSource *xsrc = &xive->source;
1626
1627 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1628 return H_FUNCTION;
1629 }
1630
1631 if (flags & ~SPAPR_XIVE_ESB_STORE) {
1632 return H_PARAMETER;
1633 }
1634
1635 if (lisn >= xive->nr_irqs) {
1636 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
1637 lisn);
1638 return H_P2;
1639 }
1640
1641 eas = xive->eat[lisn];
1642 if (!xive_eas_is_valid(&eas)) {
1643 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
1644 lisn);
1645 return H_P2;
1646 }
1647
1648 if (offset > (1ull << xsrc->esb_shift)) {
1649 return H_P3;
1650 }
1651
1652 if (kvm_irqchip_in_kernel()) {
1653 args[0] = kvmppc_xive_esb_rw(xsrc, lisn, offset, data,
1654 flags & SPAPR_XIVE_ESB_STORE);
1655 } else {
1656 mmio_addr = xive->vc_base + xive_source_esb_mgmt(xsrc, lisn) + offset;
1657
1658 if (dma_memory_rw(&address_space_memory, mmio_addr, &data, 8,
1659 (flags & SPAPR_XIVE_ESB_STORE))) {
1660 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: failed to access ESB @0x%"
1661 HWADDR_PRIx "\n", mmio_addr);
1662 return H_HARDWARE;
1663 }
1664 args[0] = (flags & SPAPR_XIVE_ESB_STORE) ? -1 : data;
1665 }
1666 return H_SUCCESS;
1667}
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686static target_ulong h_int_sync(PowerPCCPU *cpu,
1687 SpaprMachineState *spapr,
1688 target_ulong opcode,
1689 target_ulong *args)
1690{
1691 SpaprXive *xive = spapr->xive;
1692 XiveEAS eas;
1693 target_ulong flags = args[0];
1694 target_ulong lisn = args[1];
1695
1696 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1697 return H_FUNCTION;
1698 }
1699
1700 if (flags) {
1701 return H_PARAMETER;
1702 }
1703
1704 if (lisn >= xive->nr_irqs) {
1705 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Unknown LISN " TARGET_FMT_lx "\n",
1706 lisn);
1707 return H_P2;
1708 }
1709
1710 eas = xive->eat[lisn];
1711 if (!xive_eas_is_valid(&eas)) {
1712 qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid LISN " TARGET_FMT_lx "\n",
1713 lisn);
1714 return H_P2;
1715 }
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727 if (kvm_irqchip_in_kernel()) {
1728 Error *local_err = NULL;
1729
1730 kvmppc_xive_sync_source(xive, lisn, &local_err);
1731 if (local_err) {
1732 error_report_err(local_err);
1733 return H_HARDWARE;
1734 }
1735 }
1736 return H_SUCCESS;
1737}
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753static target_ulong h_int_reset(PowerPCCPU *cpu,
1754 SpaprMachineState *spapr,
1755 target_ulong opcode,
1756 target_ulong *args)
1757{
1758 SpaprXive *xive = spapr->xive;
1759 target_ulong flags = args[0];
1760
1761 if (!spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
1762 return H_FUNCTION;
1763 }
1764
1765 if (flags) {
1766 return H_PARAMETER;
1767 }
1768
1769 device_legacy_reset(DEVICE(xive));
1770
1771 if (kvm_irqchip_in_kernel()) {
1772 Error *local_err = NULL;
1773
1774 kvmppc_xive_reset(xive, &local_err);
1775 if (local_err) {
1776 error_report_err(local_err);
1777 return H_HARDWARE;
1778 }
1779 }
1780 return H_SUCCESS;
1781}
1782
1783void spapr_xive_hcall_init(SpaprMachineState *spapr)
1784{
1785 spapr_register_hypercall(H_INT_GET_SOURCE_INFO, h_int_get_source_info);
1786 spapr_register_hypercall(H_INT_SET_SOURCE_CONFIG, h_int_set_source_config);
1787 spapr_register_hypercall(H_INT_GET_SOURCE_CONFIG, h_int_get_source_config);
1788 spapr_register_hypercall(H_INT_GET_QUEUE_INFO, h_int_get_queue_info);
1789 spapr_register_hypercall(H_INT_SET_QUEUE_CONFIG, h_int_set_queue_config);
1790 spapr_register_hypercall(H_INT_GET_QUEUE_CONFIG, h_int_get_queue_config);
1791 spapr_register_hypercall(H_INT_SET_OS_REPORTING_LINE,
1792 h_int_set_os_reporting_line);
1793 spapr_register_hypercall(H_INT_GET_OS_REPORTING_LINE,
1794 h_int_get_os_reporting_line);
1795 spapr_register_hypercall(H_INT_ESB, h_int_esb);
1796 spapr_register_hypercall(H_INT_SYNC, h_int_sync);
1797 spapr_register_hypercall(H_INT_RESET, h_int_reset);
1798}
1799