Esempio n. 1
0
int
pc_madr_add(int lboard, int rboard, int proc, uint_t madr)
{
	register int	i;
	uint_t		madr_rd, madr_off;
	uint64_t	pc_madr_addr;

	pc_madr_addr = STARFIRE_PC_MADR_ADDR(lboard, rboard, proc);

	/*
	 * First write with Presence bit disabled
	 * and then with it enabled.
	 */
	madr_off = madr & ~STARFIRE_MC_MEM_PRESENT_MASK;
	stphysio(pc_madr_addr, madr_off);

	for (i = 0; i < 20; i++) {
		madr_rd = ldphysio(pc_madr_addr);
		if (madr_off == madr_rd)
			break;
	}
	if (madr_off != madr_rd) {
		cmn_err(CE_WARN,
			"pc_madr_add: (1) failed to update "
			"PC MADR (%d, %d, %d, 0x%x)\n",
			lboard, rboard, proc, madr);
		return (-1);
	}
	if (madr == madr_off) {
		/*
		 * Caller wanted to write value out there
		 * with presence bit turned off, which is
		 * what we just completed.  So, we're finished.
		 */
		return (0);
	}
	/*
	 * Now write with Presence bit enabled.
	 */
	stphysio(pc_madr_addr, madr);

	for (i = 0; i < 20; i++) {
		madr_rd = ldphysio(pc_madr_addr);
		if (madr == madr_rd)
			break;
	}
	if (madr != madr_rd) {
		cmn_err(CE_WARN,
			"pc_madr_add: (2) failed to update "
			"PC MADR (%d, %d, %d, 0x%x)\n",
			lboard, rboard, proc, madr);
		return (-1);
	}

	return (0);
}
Esempio n. 2
0
int
mc_get_dimm_size(pnode_t nodeid)
{
	uint64_t	psi_addr;
	uint_t		dimmtype;
	int		i, rlen;
	struct sf_memunit_regspec	reg;

	rlen = prom_getproplen(nodeid, "reg");
	if (rlen != sizeof (struct sf_memunit_regspec))
		return (-1);

	if (prom_getprop(nodeid, "reg", (caddr_t)&reg) < 0)
		return (-1);

	psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32;
	psi_addr |= (uint64_t)reg.regspec_addr_lo;
	psi_addr = STARFIRE_MC_DIMMTYPE_ADDR(psi_addr);

	if (psi_addr == (uint64_t)-1)
		return (-1);

	dimmtype = ldphysio(psi_addr);
	dimmtype &= STARFIRE_MC_DIMMSIZE_MASK;

	for (i = 0; dimmsize_table[i].mc_type != 0; i++)
		if (dimmsize_table[i].mc_type == dimmtype)
			break;

	return (dimmsize_table[i].mc_module_size);
}
Esempio n. 3
0
int
mc_read_asr(pnode_t nodeid, uint_t *mcregp)
{
	uint64_t	psi_addr;

	*mcregp = 0;

	psi_addr = mc_get_asr_addr(nodeid);
	if (psi_addr == (uint64_t)-1)
		return (-1);

	*mcregp = ldphysio(psi_addr);

	return (0);
}
Esempio n. 4
0
static uint_t
pcmu_pbm_error_intr(caddr_t a)
{
	pcmu_t *pcmu_p = (pcmu_t *)a;
	pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p;
	ddi_fm_error_t derr;
	int err = DDI_FM_OK;
	on_trap_data_t *otp = pcbm_p->pcbm_ontrap_data;

	bzero(&derr, sizeof (ddi_fm_error_t));
	derr.fme_version = DDI_FME_VERSION;
	mutex_enter(&pcmu_p->pcmu_err_mutex);
	if ((otp != NULL) && (otp->ot_prot & OT_DATA_ACCESS)) {
		/*
		 * ddi_poke protection, check nexus and children for
		 * expected errors.
		 */
		otp->ot_trap |= OT_DATA_ACCESS;
		membar_sync();
		derr.fme_flag = DDI_FM_ERR_POKE;
		err = pcmu_pbm_err_handler(pcmu_p->pcmu_dip, &derr,
		    (void *)pcmu_p, PCI_INTR_CALL);
	} else if (pcmu_check_error(pcmu_p) != 0) {
		/*
		 * unprotected error, check for all errors.
		 */
		if (pcmu_errtrig_pa) {
			(void) ldphysio(pcmu_errtrig_pa);
		}
		derr.fme_flag = DDI_FM_ERR_UNEXPECTED;
		err = pcmu_pbm_err_handler(pcmu_p->pcmu_dip, &derr,
		    (void *)pcmu_p, PCI_INTR_CALL);
	}

	if (err == DDI_FM_FATAL) {
		if (pcmu_panic_on_fatal_errors) {
			mutex_exit(&pcmu_p->pcmu_err_mutex);
			cmn_err(CE_PANIC, "%s-%d: Fatal PCI bus error(s)\n",
			    ddi_driver_name(pcmu_p->pcmu_dip),
			    ddi_get_instance(pcmu_p->pcmu_dip));
		}
	}

	mutex_exit(&pcmu_p->pcmu_err_mutex);
	pcmu_ib_nintr_clear(pcmu_p->pcmu_ib_p, pcmu_p->pcmu_inos[CBNINTR_PBM]);
	return (DDI_INTR_CLAIMED);
}
Esempio n. 5
0
int
mc_write_asr(pnode_t nodeid, uint_t mcreg)
{
	uint_t		mcreg_rd;
	uint64_t	psi_addr;

	psi_addr = mc_get_asr_addr(nodeid);
	if (psi_addr == (uint64_t)-1)
		return (-1);

	stphysio(psi_addr, mcreg);

	mcreg_rd = ldphysio(psi_addr);
	ASSERT(mcreg_rd == mcreg);

	return ((mcreg_rd != mcreg) ? -1 : 0);
}
Esempio n. 6
0
uint64_t
mc_get_alignment_mask(pnode_t nodeid)
{
	uint64_t	psi_addr, seg_sz;
	uint_t		mcreg, seg_sz_mask;
	int		i, rlen;
	struct sf_memunit_regspec	reg;

	rlen = prom_getproplen(nodeid, "reg");
	if (rlen != sizeof (struct sf_memunit_regspec))
		return (-1);

	if (prom_getprop(nodeid, "reg", (caddr_t)&reg) < 0)
		return (-1);

	psi_addr = ((uint64_t)reg.regspec_addr_hi) << 32;
	psi_addr |= (uint64_t)reg.regspec_addr_lo;
	psi_addr = STARFIRE_MC_ASR_ADDR(psi_addr);

	if (psi_addr == (uint64_t)-1)
		return (-1);

	mcreg = ldphysio(psi_addr);
	seg_sz_mask = (mcreg & STARFIRE_MC_MASK_MASK) >> 8;

	for (i = 0; mc_seg_table[i].seg_size != 0; i++)
		if (mc_seg_table[i].seg_mask == seg_sz_mask)
			break;

	if (mc_seg_table[i].seg_size == 0)
		seg_sz = mc_get_mem_alignment();
	else
		seg_sz = mc_seg_table[i].seg_size;

#ifdef DEBUG
	printf("nodeid %x, mc asr addr %lx, val %x, seg_sz_mask %x, "
	    "seg_sz %lx\n", nodeid, psi_addr, mcreg, seg_sz_mask, seg_sz);
#endif /* DEBUG */

	return (seg_sz - 1);
}