static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq) { ICSState *ics = spapr->ics; uint32_t srcno = irq - ics->offset; if (ics_valid_irq(ics, irq)) { return ics->qirqs[srcno]; } return NULL; }
/* * Exported functions */ static int xics_find_source(XICSState *icp, int irq) { int sources = 1; int src; /* FIXME: implement multiple sources */ for (src = 0; src < sources; ++src) { ICSState *ics = &icp->ics[src]; if (ics_valid_irq(ics, irq)) { return src; } } return -1; }
static void spapr_irq_free_xics(sPAPRMachineState *spapr, int irq, int num) { ICSState *ics = spapr->ics; uint32_t srcno = irq - ics->offset; int i; if (ics_valid_irq(ics, irq)) { trace_spapr_irq_free(0, irq, num); for (i = srcno; i < srcno + num; ++i) { if (ICS_IRQ_FREE(ics, i)) { trace_spapr_irq_free_warn(0, i); } memset(&ics->irqs[i], 0, sizeof(ICSIRQState)); } } }
static int spapr_irq_claim_xics(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp) { ICSState *ics = spapr->ics; assert(ics); if (!ics_valid_irq(ics, irq)) { error_setg(errp, "IRQ %d is invalid", irq); return -1; } if (!ICS_IRQ_FREE(ics, irq - ics->offset)) { error_setg(errp, "IRQ %d is not free", irq); return -1; } ics_set_irq_type(ics, irq - ics->offset, lsi); return 0; }
static void rtas_get_xive(sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { struct ics_state *ics = spapr->icp->ics; uint32_t nr; if ((nargs != 1) || (nret != 3)) { rtas_st(rets, 0, -3); return; } nr = rtas_ld(args, 0); if (!ics_valid_irq(ics, nr)) { rtas_st(rets, 0, -3); return; } rtas_st(rets, 0, 0); /* Success */ rtas_st(rets, 1, ics->irqs[nr - ics->offset].server); rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority); }
static void rtas_int_on(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { struct ics_state *ics = vcpu->kvm->icp->ics; uint32_t nr; if ((nargs != 1) || (nret != 1)) { rtas_st(vcpu->kvm, rets, 0, -3); return; } nr = rtas_ld(vcpu->kvm, args, 0); if (!ics_valid_irq(ics, nr)) { rtas_st(vcpu->kvm, rets, 0, -3); return; } /* ME: QEMU wrote xive_msi here, in #if 0. Deleted. */ rtas_st(vcpu->kvm, rets, 0, 0); /* Success */ }
static void rtas_get_xive(struct kvm_cpu *vcpu, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { struct ics_state *ics = vcpu->kvm->icp->ics; uint32_t nr; if ((nargs != 1) || (nret != 3)) { rtas_st(vcpu->kvm, rets, 0, -3); return; } nr = rtas_ld(vcpu->kvm, args, 0); if (!ics_valid_irq(ics, nr)) { rtas_st(vcpu->kvm, rets, 0, -3); return; } rtas_st(vcpu->kvm, rets, 0, 0); /* Success */ rtas_st(vcpu->kvm, rets, 1, ics->irqs[nr - ics->offset].server); rtas_st(vcpu->kvm, rets, 2, ics->irqs[nr - ics->offset].priority); }
static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { ICSState *ics = spapr->icp->ics; uint32_t nr; if ((nargs != 1) || (nret != 3)) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } nr = rtas_ld(args, 0); if (!ics_valid_irq(ics, nr)) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } rtas_st(rets, 0, RTAS_OUT_SUCCESS); rtas_st(rets, 1, ics->irqs[nr - ics->offset].server); rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority); }
void xics_set_irq_type(XICSState *icp, int irq, bool lsi) { assert(ics_valid_irq(icp->ics, irq)); icp->ics->islsi[irq - icp->ics->offset] = lsi; }