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