Lines Matching +full:cpu +full:- +full:intc
7 * COPYING file in the top-level directory.
12 #include "qemu/error-report.h"
20 #include "hw/qdev-properties.h"
21 #include "cpu-models.h"
36 if (SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { in spapr_irq_msi_init()
41 spapr->irq_map_nr = spapr_irq_nr_msis(spapr); in spapr_irq_msi_init()
42 spapr->irq_map = bitmap_new(spapr->irq_map_nr); in spapr_irq_msi_init()
56 align -= 1; in spapr_irq_msi_alloc()
58 irq = bitmap_find_next_zero_area(spapr->irq_map, spapr->irq_map_nr, 0, num, in spapr_irq_msi_alloc()
60 if (irq == spapr->irq_map_nr) { in spapr_irq_msi_alloc()
61 error_setg(errp, "can't find a free %d-IRQ block", num); in spapr_irq_msi_alloc()
62 return -1; in spapr_irq_msi_alloc()
65 bitmap_set(spapr->irq_map, irq, num); in spapr_irq_msi_alloc()
72 bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); in spapr_irq_msi_free()
76 SpaprInterruptController *intc, in spapr_irq_init_kvm() argument
83 if (fn(intc, nr_servers, &local_err) < 0) { in spapr_irq_init_kvm()
88 return -1; in spapr_irq_init_kvm()
98 "Falling back to kernel-irqchip=off\n"); in spapr_irq_init_kvm()
148 * Sanity checks on non-P9 machines. On these, XIVE is not in spapr_irq_check()
151 if (!ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, in spapr_irq_check()
152 0, spapr->max_compat_pvr)) { in spapr_irq_check()
157 if (spapr->irq == &spapr_irq_dual) { in spapr_irq_check()
158 spapr->irq = &spapr_irq_xics; in spapr_irq_check()
163 * Non-P9 machines using only XIVE is a bogus setup. We have two in spapr_irq_check()
177 if (!spapr->irq->xics) { in spapr_irq_check()
178 error_setg(errp, "XIVE-only machines require a POWER9 CPU"); in spapr_irq_check()
179 return -1; in spapr_irq_check()
185 * re-created. Same happens with KVM nested guests. Detect that early to in spapr_irq_check()
189 spapr->irq == &spapr_irq_dual && in spapr_irq_check()
193 "KVM is incompatible with ic-mode=dual,kernel-irqchip=on"); in spapr_irq_check()
197 "Try without kernel-irqchip or with kernel-irqchip=off.\n"); in spapr_irq_check()
198 return -1; in spapr_irq_check()
208 { SPAPR_INTC((spapr_)->ics), SPAPR_INTC((spapr_)->xive), }
211 PowerPCCPU *cpu, Error **errp) in spapr_irq_cpu_intc_create() argument
218 SpaprInterruptController *intc = intcs[i]; in spapr_irq_cpu_intc_create() local
219 if (intc) { in spapr_irq_cpu_intc_create()
220 SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); in spapr_irq_cpu_intc_create()
221 rc = sicc->cpu_intc_create(intc, cpu, errp); in spapr_irq_cpu_intc_create()
231 void spapr_irq_cpu_intc_reset(SpaprMachineState *spapr, PowerPCCPU *cpu) in spapr_irq_cpu_intc_reset() argument
237 SpaprInterruptController *intc = intcs[i]; in spapr_irq_cpu_intc_reset() local
238 if (intc) { in spapr_irq_cpu_intc_reset()
239 SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); in spapr_irq_cpu_intc_reset()
240 sicc->cpu_intc_reset(intc, cpu); in spapr_irq_cpu_intc_reset()
245 void spapr_irq_cpu_intc_destroy(SpaprMachineState *spapr, PowerPCCPU *cpu) in spapr_irq_cpu_intc_destroy() argument
251 SpaprInterruptController *intc = intcs[i]; in spapr_irq_cpu_intc_destroy() local
252 if (intc) { in spapr_irq_cpu_intc_destroy()
253 SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); in spapr_irq_cpu_intc_destroy()
254 sicc->cpu_intc_destroy(intc, cpu); in spapr_irq_cpu_intc_destroy()
263 = SPAPR_INTC_GET_CLASS(spapr->active_intc); in spapr_set_irq()
265 sicc->set_irq(spapr->active_intc, irq, level); in spapr_set_irq()
271 = SPAPR_INTC_GET_CLASS(spapr->active_intc); in spapr_irq_print_info()
273 sicc->print_info(spapr->active_intc, buf); in spapr_irq_print_info()
280 = SPAPR_INTC_GET_CLASS(spapr->active_intc); in spapr_irq_dt()
282 sicc->dt(spapr->active_intc, nr_servers, fdt, phandle); in spapr_irq_dt()
289 if (smc->legacy_irq_allocation) { in spapr_irq_nr_msis()
290 return smc->nr_xirqs; in spapr_irq_nr_msis()
292 return SPAPR_XIRQ_BASE + smc->nr_xirqs - SPAPR_IRQ_MSI; in spapr_irq_nr_msis()
312 if (spapr->irq->xics) { in spapr_irq_init()
320 object_property_set_int(obj, "nr-irqs", smc->nr_xirqs, &error_abort); in spapr_irq_init()
325 spapr->ics = ICS_SPAPR(obj); in spapr_irq_init()
328 if (spapr->irq->xive) { in spapr_irq_init()
334 qdev_prop_set_uint32(dev, "nr-irqs", smc->nr_xirqs + SPAPR_IRQ_NR_IPIS); in spapr_irq_init()
336 * 8 XIVE END structures per CPU. One for each available in spapr_irq_init()
339 qdev_prop_set_uint32(dev, "nr-ends", nr_servers << 3); in spapr_irq_init()
340 object_property_set_link(OBJECT(dev), "xive-fabric", OBJECT(spapr), in spapr_irq_init()
344 spapr->xive = SPAPR_XIVE(dev); in spapr_irq_init()
346 /* Enable the CPU IPIs */ in spapr_irq_init()
349 = SPAPR_INTC_GET_CLASS(spapr->xive); in spapr_irq_init()
351 if (sicc->claim_irq(SPAPR_INTC(spapr->xive), SPAPR_IRQ_IPI + i, in spapr_irq_init()
360 spapr->qirqs = qemu_allocate_irqs(spapr_set_irq, spapr, in spapr_irq_init()
361 smc->nr_xirqs + SPAPR_IRQ_NR_IPIS); in spapr_irq_init()
366 * false-positive warning during realize(), because they don't yet in spapr_irq_init()
367 * have an in-kernel irq chip. in spapr_irq_init()
380 assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE)); in spapr_irq_claim()
383 SpaprInterruptController *intc = intcs[i]; in spapr_irq_claim() local
384 if (intc) { in spapr_irq_claim()
385 SpaprInterruptControllerClass *sicc = SPAPR_INTC_GET_CLASS(intc); in spapr_irq_claim()
386 rc = sicc->claim_irq(intc, irq, lsi, errp); in spapr_irq_claim()
403 assert((irq + num) <= (smc->nr_xirqs + SPAPR_XIRQ_BASE)); in spapr_irq_free()
407 SpaprInterruptController *intc = intcs[j]; in spapr_irq_free() local
409 if (intc) { in spapr_irq_free()
411 = SPAPR_INTC_GET_CLASS(intc); in spapr_irq_free()
412 sicc->free_irq(intc, i); in spapr_irq_free()
430 assert(irq < (smc->nr_xirqs + SPAPR_XIRQ_BASE)); in spapr_qirq()
432 if (spapr->ics) { in spapr_qirq()
433 assert(ics_valid_irq(spapr->ics, irq)); in spapr_qirq()
435 if (spapr->xive) { in spapr_qirq()
436 assert(irq < spapr->xive->nr_irqs); in spapr_qirq()
437 assert(xive_eas_is_valid(&spapr->xive->eat[irq])); in spapr_qirq()
440 return spapr->qirqs[irq]; in spapr_qirq()
448 sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc); in spapr_irq_post_load()
449 return sicc->post_load(spapr->active_intc, version_id); in spapr_irq_post_load()
454 assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); in spapr_irq_reset()
461 const char *nodename = "interrupt-controller"; in spapr_irq_get_phandle()
468 return -1; in spapr_irq_get_phandle()
474 return -1; in spapr_irq_get_phandle()
488 if (new_intc == spapr->active_intc) { in set_active_intc()
493 if (spapr->active_intc) { in set_active_intc()
494 sicc = SPAPR_INTC_GET_CLASS(spapr->active_intc); in set_active_intc()
495 if (sicc->deactivate) { in set_active_intc()
496 sicc->deactivate(spapr->active_intc); in set_active_intc()
501 if (sicc->activate) { in set_active_intc()
502 sicc->activate(new_intc, nr_servers, &error_fatal); in set_active_intc()
505 spapr->active_intc = new_intc; in set_active_intc()
518 if (!spapr->ics) { in spapr_irq_update_active_intc()
521 * indicates XICS, even if we have ic-mode=xive. TODO: clean in spapr_irq_update_active_intc()
525 new_intc = SPAPR_INTC(spapr->xive); in spapr_irq_update_active_intc()
526 } else if (spapr->ov5_cas in spapr_irq_update_active_intc()
527 && spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { in spapr_irq_update_active_intc()
528 new_intc = SPAPR_INTC(spapr->xive); in spapr_irq_update_active_intc()
530 new_intc = SPAPR_INTC(spapr->ics); in spapr_irq_update_active_intc()
537 * XICS legacy routines - to deprecate one day
544 for (first = 0; first < ics->nr_irqs; first += alignnum) { in ics_find_free_block()
545 if (num > (ics->nr_irqs - first)) { in ics_find_free_block()
546 return -1; in ics_find_free_block()
558 return -1; in ics_find_free_block()
563 ICSState *ics = spapr->ics; in spapr_irq_find()
564 int first = -1; in spapr_irq_find()
571 * MSI vectors. MSI-X is not affected by this. in spapr_irq_find()
584 error_setg(errp, "can't find a free %d-IRQ block", num); in spapr_irq_find()
585 return -1; in spapr_irq_find()
588 return first + ics->offset; in spapr_irq_find()