Esempio n. 1
0
void
pcmu_pbm_create(pcmu_t *pcmu_p)
{
	pcmu_pbm_t *pcbm_p;
	int len;
	dev_info_t *dip = pcmu_p->pcmu_dip;

	/*
	 * Allocate a state structure for the PBM and cross-link it
	 * to its per pci node state structure.
	 */
	pcbm_p = (pcmu_pbm_t *)kmem_zalloc(sizeof (pcmu_pbm_t), KM_SLEEP);
	pcmu_p->pcmu_pcbm_p = pcbm_p;
	pcbm_p->pcbm_pcmu_p = pcmu_p;

	len = snprintf(pcbm_p->pcbm_nameinst_str,
	    sizeof (pcbm_p->pcbm_nameinst_str), "%s%d", NAMEINST(dip));
	pcbm_p->pcbm_nameaddr_str = pcbm_p->pcbm_nameinst_str + ++len;
	(void) snprintf(pcbm_p->pcbm_nameaddr_str,
	    sizeof (pcbm_p->pcbm_nameinst_str) - len, "%s@%s", NAMEADDR(dip));

	pcmu_pbm_setup(pcbm_p);

	PCMU_DBG4(PCMU_DBG_ATTACH, dip,
	    "pcmu_pbm_create: ctrl=%x, afsr=%x, afar=%x, diag=%x\n",
	    pcbm_p->pcbm_ctrl_reg, pcbm_p->pcbm_async_flt_status_reg,
	    pcbm_p->pcbm_async_flt_addr_reg, pcbm_p->pcbm_diag_reg);
	PCMU_DBG1(PCMU_DBG_ATTACH, dip, "pcmu_pbm_create: conf=%x\n",
	    pcbm_p->pcbm_config_header);

	/*
	 * Register a function to disable pbm error interrupts during a panic.
	 */
	bus_func_register(BF_TYPE_ERRDIS,
	    (busfunc_t)pcmu_pbm_disable_errors, pcbm_p);

	/*
	 * create the interrupt-priorities property if it doesn't
	 * already exist to provide a hint as to the PIL level for
	 * our interrupt.
	 */
	if (ddi_getproplen(DDI_DEV_T_ANY, dip,
	    DDI_PROP_DONTPASS, "interrupt-priorities",
	    &len) != DDI_PROP_SUCCESS) {
		/* Create the interrupt-priorities property. */
		(void) ddi_prop_create(DDI_DEV_T_NONE, dip,
		    DDI_PROP_CANSLEEP, "interrupt-priorities",
		    (caddr_t)pcmu_pil, sizeof (pcmu_pil));
	}
	pcmu_pbm_configure(pcbm_p);
}
Esempio n. 2
0
int
px_pec_attach(px_t *px_p)
{
	px_pec_t *pec_p;
	int i, len;
	int nrange = px_p->px_ranges_length / sizeof (px_ranges_t);
	dev_info_t *dip = px_p->px_dip;
	px_ranges_t *rangep = px_p->px_ranges_p;
	int ret;

	/*
	 * Allocate a state structure for the PEC and cross-link it
	 * to its per px node state structure.
	 */
	pec_p = kmem_zalloc(sizeof (px_pec_t), KM_SLEEP);
	px_p->px_pec_p = pec_p;
	pec_p->pec_px_p = px_p;

	len = snprintf(pec_p->pec_nameinst_str,
		sizeof (pec_p->pec_nameinst_str),
		"%s%d", NAMEINST(dip));
	pec_p->pec_nameaddr_str = pec_p->pec_nameinst_str + ++len;
	(void) snprintf(pec_p->pec_nameaddr_str,
		sizeof (pec_p->pec_nameinst_str) - len,
		"%s@%s", NAMEADDR(dip));

	/*
	 * Add interrupt handlers to process correctable/fatal/non fatal
	 * PCIE messages.
	 */
	if ((ret = px_pec_msg_add_intr(px_p)) != DDI_SUCCESS) {
		px_pec_msg_rem_intr(px_p);
		return (ret);
	}

	/*
	 * Get this pec's mem32 and mem64 segments to determine whether
	 * a dma object originates from ths pec. i.e. dev to dev dma
	 */
	for (i = 0; i < nrange; i++, rangep++) {
		uint64_t rng_addr, rng_size, *pfnbp, *pfnlp;
		uint32_t rng_type = rangep->child_high & PCI_ADDR_MASK;

		switch (rng_type) {
			case PCI_ADDR_MEM32:
				pfnbp = &pec_p->pec_base32_pfn;
				pfnlp = &pec_p->pec_last32_pfn;
				break;

			case PCI_ADDR_MEM64:
				pfnbp = &pec_p->pec_base64_pfn;
				pfnlp = &pec_p->pec_last64_pfn;
				break;

			case PCI_ADDR_CONFIG:
			case PCI_ADDR_IO:
			default:
				continue;
		}
		rng_addr = (uint64_t)(rangep->parent_high &
					px_ranges_phi_mask) << 32;
		rng_addr |= (uint64_t)rangep->parent_low;
		rng_size = (uint64_t)rangep->size_high << 32;
		rng_size |= (uint64_t)rangep->size_low;

		*pfnbp = mmu_btop(rng_addr);
		*pfnlp = mmu_btop(rng_addr + rng_size);
	}

	mutex_init(&pec_p->pec_pokefault_mutex, NULL, MUTEX_DRIVER,
	    (void *)px_p->px_fm_ibc);

	return (DDI_SUCCESS);
}