void gcpu_mca_poll_start(cmi_hdl_t hdl) { ASSERT(cmi_hdl_class(hdl) == CMI_HDL_SOLARIS_xVM_MCA); /* * We are on the boot cpu (cpu 0), called at the end of its * multiprocessor startup. */ if (gcpu_xpv_poll_bankregs_sz != 0 && gcpu_xpv_virq_vect == -1) { /* * The hypervisor will poll MCA state for us, but it cannot * poll MCH state so we do that via a timeout. */ if (gcpu_xpv_mch_poll_interval_secs != 0) { gcpu_xpv_mch_poll_timeoutid = timeout(gcpu_xpv_mch_poll, GCPU_XPV_MCH_POLL_REARM, drv_usectohz(gcpu_xpv_mch_poll_interval_secs * MICROSEC)); } /* * Register handler for VIRQ_MCA; once this is in place * the hypervisor will begin to forward polled MCA observations * to us. */ gcpu_xpv_virq_vect = ec_bind_virq_to_irq(VIRQ_MCA, 0); (void) add_avintr(NULL, gcpu_xpv_virq_level, (avfunc)gcpu_xpv_virq_intr, "MCA", gcpu_xpv_virq_vect, NULL, NULL, NULL, NULL); } }
static int evtchndrv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int error; int unit = ddi_get_instance(dip); switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: return (DDI_SUCCESS); default: cmn_err(CE_WARN, "evtchn_attach: unknown cmd 0x%x\n", cmd); return (DDI_FAILURE); } /* DDI_ATTACH */ /* * only one instance - but we clone using the open routine */ if (ddi_get_instance(dip) > 0) return (DDI_FAILURE); mutex_init(&evtchndrv_clone_tab_mutex, NULL, MUTEX_DRIVER, NULL); error = ddi_create_minor_node(dip, "evtchn", S_IFCHR, unit, DDI_PSEUDO, NULL); if (error != DDI_SUCCESS) goto fail; /* * save dip for getinfo */ evtchndrv_dip = dip; ddi_report_dev(dip); mutex_init(&port_user_lock, NULL, MUTEX_DRIVER, NULL); (void) memset(port_user, 0, sizeof (port_user)); ec_dev_irq = ec_dev_alloc_irq(); (void) add_avintr(NULL, IPL_EVTCHN, (avfunc)evtchn_device_upcall, "evtchn_driver", ec_dev_irq, NULL, NULL, NULL, dip); return (DDI_SUCCESS); fail: (void) evtchndrv_detach(dip, DDI_DETACH); return (error); }
void xb_setup_intr(void) { #ifdef XPV_HVM_DRIVER ec_bind_evtchn_to_handler(xen_info->store_evtchn, IPL_XENBUS, xenbus_intr, NULL); #else xenbus_irq = ec_bind_evtchn_to_irq(xen_info->store_evtchn); if (xenbus_irq < 0) { cmn_err(CE_WARN, "Couldn't bind xenbus event channel"); return; } if (!add_avintr(NULL, IPL_XENBUS, (avfunc)xenbus_intr, "xenbus", xenbus_irq, NULL, NULL, NULL, NULL)) cmn_err(CE_WARN, "XENBUS add intr failed\n"); #endif }
static int isa_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result) { struct intrspec *ispec; #if defined(__xpv) int cons, ttyn; cons = console_hypervisor_dev_type(&ttyn); #endif if (pseudo_isa) return (i_ddi_intr_ops(pdip, rdip, intr_op, hdlp, result)); /* Process the interrupt operation */ switch (intr_op) { case DDI_INTROP_GETCAP: /* First check with pcplusmp */ if (psm_intr_ops == NULL) return (DDI_FAILURE); if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_GET_CAP, result)) { *(int *)result = 0; return (DDI_FAILURE); } break; case DDI_INTROP_SETCAP: if (psm_intr_ops == NULL) return (DDI_FAILURE); if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_SET_CAP, result)) return (DDI_FAILURE); break; case DDI_INTROP_ALLOC: ASSERT(hdlp->ih_type == DDI_INTR_TYPE_FIXED); return (isa_alloc_intr_fixed(rdip, hdlp, result)); case DDI_INTROP_FREE: ASSERT(hdlp->ih_type == DDI_INTR_TYPE_FIXED); return (isa_free_intr_fixed(rdip, hdlp)); case DDI_INTROP_GETPRI: if ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL) return (DDI_FAILURE); *(int *)result = ispec->intrspec_pri; break; case DDI_INTROP_SETPRI: /* Validate the interrupt priority passed to us */ if (*(int *)result > LOCK_LEVEL) return (DDI_FAILURE); /* Ensure that PSM is all initialized and ispec is ok */ if ((psm_intr_ops == NULL) || ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL)) return (DDI_FAILURE); /* update the ispec with the new priority */ ispec->intrspec_pri = *(int *)result; break; case DDI_INTROP_ADDISR: if ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL) return (DDI_FAILURE); ispec->intrspec_func = hdlp->ih_cb_func; break; case DDI_INTROP_REMISR: if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) return (DDI_FAILURE); if ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL) return (DDI_FAILURE); ispec->intrspec_func = (uint_t (*)()) 0; break; case DDI_INTROP_ENABLE: if ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL) return (DDI_FAILURE); /* Call psmi to translate irq with the dip */ if (psm_intr_ops == NULL) return (DDI_FAILURE); #if defined(__xpv) /* * if the hypervisor is using an isa serial port for the * console, make sure we don't try to use that interrupt as * it will cause us to panic when xen_bind_pirq() fails. */ if (cons == CONS_TTY && ispec->intrspec_vec == asy_intrs[ttyn]) return (DDI_FAILURE); #endif ((ihdl_plat_t *)hdlp->ih_private)->ip_ispecp = ispec; if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_XLATE_VECTOR, (int *)&hdlp->ih_vector) == PSM_FAILURE) return (DDI_FAILURE); /* Add the interrupt handler */ if (!add_avintr((void *)hdlp, ispec->intrspec_pri, hdlp->ih_cb_func, DEVI(rdip)->devi_name, hdlp->ih_vector, hdlp->ih_cb_arg1, hdlp->ih_cb_arg2, NULL, rdip)) return (DDI_FAILURE); break; case DDI_INTROP_DISABLE: if ((ispec = isa_get_ispec(rdip, hdlp->ih_inum)) == NULL) return (DDI_FAILURE); /* Call psm_ops() to translate irq with the dip */ if (psm_intr_ops == NULL) return (DDI_FAILURE); ((ihdl_plat_t *)hdlp->ih_private)->ip_ispecp = ispec; (void) (*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_XLATE_VECTOR, (int *)&hdlp->ih_vector); /* Remove the interrupt handler */ rem_avintr((void *)hdlp, ispec->intrspec_pri, hdlp->ih_cb_func, hdlp->ih_vector); break; case DDI_INTROP_SETMASK: if (psm_intr_ops == NULL) return (DDI_FAILURE); if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_SET_MASK, NULL)) return (DDI_FAILURE); break; case DDI_INTROP_CLRMASK: if (psm_intr_ops == NULL) return (DDI_FAILURE); if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_CLEAR_MASK, NULL)) return (DDI_FAILURE); break; case DDI_INTROP_GETPENDING: if (psm_intr_ops == NULL) return (DDI_FAILURE); if ((*psm_intr_ops)(rdip, hdlp, PSM_INTR_OP_GET_PENDING, result)) { *(int *)result = 0; return (DDI_FAILURE); } break; case DDI_INTROP_NAVAIL: case DDI_INTROP_NINTRS: *(int *)result = i_ddi_get_intx_nintrs(rdip); if (*(int *)result == 0) { return (DDI_FAILURE); } break; case DDI_INTROP_SUPPORTED_TYPES: *(int *)result = DDI_INTR_TYPE_FIXED; /* Always ... */ break; default: return (DDI_FAILURE); } return (DDI_SUCCESS); }
int psm_add_intr(int lvl, avfunc xxintr, char *name, int vect, caddr_t arg) { return (add_avintr((void *)NULL, lvl, xxintr, name, vect, arg, NULL, NULL, NULL)); }