⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_schizo.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (pbm == &p->pbm_A)		regbase += SCHIZO_PBM_A_REGS_OFF;	else		regbase += SCHIZO_PBM_B_REGS_OFF;	err_base = regbase + SCHIZO_STC_ERR;	tag_base = regbase + SCHIZO_STC_TAG;	line_base = regbase + SCHIZO_STC_LINE;	spin_lock(&stc_buf_lock);	/* This is __REALLY__ dangerous.  When we put the	 * streaming buffer into diagnostic mode to probe	 * it's tags and error status, we _must_ clear all	 * of the line tag valid bits before re-enabling	 * the streaming buffer.  If any dirty data lives	 * in the STC when we do this, we will end up	 * invalidating it before it has a chance to reach	 * main memory.	 */	control = schizo_read(strbuf->strbuf_control);	schizo_write(strbuf->strbuf_control,		     (control | SCHIZO_STRBUF_CTRL_DENAB));	for (i = 0; i < 128; i++) {		unsigned long val;		val = schizo_read(err_base + (i * 8UL));		schizo_write(err_base + (i * 8UL), 0UL);		stc_error_buf[i] = val;	}	for (i = 0; i < 16; i++) {		stc_tag_buf[i] = schizo_read(tag_base + (i * 8UL));		stc_line_buf[i] = schizo_read(line_base + (i * 8UL));		schizo_write(tag_base + (i * 8UL), 0UL);		schizo_write(line_base + (i * 8UL), 0UL);	}	/* OK, state is logged, exit diagnostic mode. */	schizo_write(strbuf->strbuf_control, control);	for (i = 0; i < 16; i++) {		int j, saw_error, first, last;		saw_error = 0;		first = i * 8;		last = first + 8;		for (j = first; j < last; j++) {			unsigned long errval = stc_error_buf[j];			if (errval != 0) {				saw_error++;				printk("SCHIZO%d: PBM-%c STC_ERR(%d)[wr(%d)rd(%d)]\n",				       p->index, pbm_name,				       j,				       (errval & SCHIZO_STCERR_WRITE) ? 1 : 0,				       (errval & SCHIZO_STCERR_READ) ? 1 : 0);			}		}		if (saw_error != 0) {			unsigned long tagval = stc_tag_buf[i];			unsigned long lineval = stc_line_buf[i];			printk("SCHIZO%d: PBM-%c STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)R(%d)]\n",			       p->index, pbm_name,			       i,			       ((tagval & SCHIZO_STCTAG_PPN) >> 19UL),			       (tagval & SCHIZO_STCTAG_VPN),			       ((tagval & SCHIZO_STCTAG_VALID) ? 1 : 0),			       ((tagval & SCHIZO_STCTAG_READ) ? 1 : 0));			/* XXX Should spit out per-bank error information... -DaveM */			printk("SCHIZO%d: PBM-%c STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)"			       "V(%d)FOFN(%d)]\n",			       p->index, pbm_name,			       i,			       ((lineval & SCHIZO_STCLINE_LINDX) >> 23UL),			       ((lineval & SCHIZO_STCLINE_SPTR) >> 13UL),			       ((lineval & SCHIZO_STCLINE_LADDR) >> 6UL),			       ((lineval & SCHIZO_STCLINE_EPTR) >> 0UL),			       ((lineval & SCHIZO_STCLINE_VALID) ? 1 : 0),			       ((lineval & SCHIZO_STCLINE_FOFN) ? 1 : 0));		}	}	spin_unlock(&stc_buf_lock);}/* IOMMU is per-PBM in Schizo, so interrogate both for anonymous * controller level errors. */#define SCHIZO_IOMMU_TAG	0xa580UL#define SCHIZO_IOMMU_DATA	0xa600UL#define SCHIZO_IOMMU_TAG_CTXT	0x0000001ffe000000UL#define SCHIZO_IOMMU_TAG_ERRSTS	0x0000000001800000UL#define SCHIZO_IOMMU_TAG_ERR	0x0000000000400000UL#define SCHIZO_IOMMU_TAG_WRITE	0x0000000000200000UL#define SCHIZO_IOMMU_TAG_STREAM	0x0000000000100000UL#define SCHIZO_IOMMU_TAG_SIZE	0x0000000000080000UL#define SCHIZO_IOMMU_TAG_VPAGE	0x000000000007ffffUL#define SCHIZO_IOMMU_DATA_VALID	0x0000000100000000UL#define SCHIZO_IOMMU_DATA_CACHE	0x0000000040000000UL#define SCHIZO_IOMMU_DATA_PPAGE	0x000000003fffffffULstatic void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm,					 enum schizo_error_type type){	struct pci_controller_info *p = pbm->parent;	struct pci_iommu *iommu = pbm->iommu;	unsigned long iommu_tag[16];	unsigned long iommu_data[16];	unsigned long flags;	u64 control;	char pbm_name = (pbm == &p->pbm_A ? 'A' : 'B');	int i;	spin_lock_irqsave(&iommu->lock, flags);	control = schizo_read(iommu->iommu_control);	if (control & SCHIZO_IOMMU_CTRL_XLTEERR) {		unsigned long base;		char *type_string;		/* Clear the error encountered bit. */		control &= ~SCHIZO_IOMMU_CTRL_XLTEERR;		schizo_write(iommu->iommu_control, control);		switch((control & SCHIZO_IOMMU_CTRL_XLTESTAT) >> 25UL) {		case 0:			type_string = "Protection Error";			break;		case 1:			type_string = "Invalid Error";			break;		case 2:			type_string = "TimeOut Error";			break;		case 3:		default:			type_string = "ECC Error";			break;		};		printk("SCHIZO%d: PBM-%c IOMMU Error, type[%s]\n",		       p->index, pbm_name, type_string);		/* Put the IOMMU into diagnostic mode and probe		 * it's TLB for entries with error status.		 *		 * It is very possible for another DVMA to occur		 * while we do this probe, and corrupt the system		 * further.  But we are so screwed at this point		 * that we are likely to crash hard anyways, so		 * get as much diagnostic information to the		 * console as we can.		 */		schizo_write(iommu->iommu_control,			     control | SCHIZO_IOMMU_CTRL_DENAB);		base = p->controller_regs;		if (pbm == &p->pbm_A)			base += SCHIZO_PBM_A_REGS_OFF;		else			base += SCHIZO_PBM_B_REGS_OFF;		for (i = 0; i < 16; i++) {			iommu_tag[i] =				schizo_read(base + SCHIZO_IOMMU_TAG + (i * 8UL));			iommu_data[i] =				schizo_read(base + SCHIZO_IOMMU_DATA + (i * 8UL));			/* Now clear out the entry. */			schizo_write(base + SCHIZO_IOMMU_TAG + (i * 8UL), 0);			schizo_write(base + SCHIZO_IOMMU_DATA + (i * 8UL), 0);		}		/* Leave diagnostic mode. */		schizo_write(iommu->iommu_control, control);		for (i = 0; i < 16; i++) {			unsigned long tag, data;			tag = iommu_tag[i];			if (!(tag & SCHIZO_IOMMU_TAG_ERR))				continue;			data = iommu_data[i];			switch((tag & SCHIZO_IOMMU_TAG_ERRSTS) >> 23UL) {			case 0:				type_string = "Protection Error";				break;			case 1:				type_string = "Invalid Error";				break;			case 2:				type_string = "TimeOut Error";				break;			case 3:			default:				type_string = "ECC Error";				break;			};			printk("SCHIZO%d: PBM-%c IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) "			       "sz(%dK) vpg(%08lx)]\n",			       p->index, pbm_name, i, type_string,			       (int)((tag & SCHIZO_IOMMU_TAG_CTXT) >> 25UL),			       ((tag & SCHIZO_IOMMU_TAG_WRITE) ? 1 : 0),			       ((tag & SCHIZO_IOMMU_TAG_STREAM) ? 1 : 0),			       ((tag & SCHIZO_IOMMU_TAG_SIZE) ? 64 : 8),			       (tag & SCHIZO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT);			printk("SCHIZO%d: PBM-%c IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n",			       p->index, pbm_name, i,			       ((data & SCHIZO_IOMMU_DATA_VALID) ? 1 : 0),			       ((data & SCHIZO_IOMMU_DATA_CACHE) ? 1 : 0),			       (data & SCHIZO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);		}	}	__schizo_check_stc_error_pbm(pbm, type);	spin_unlock_irqrestore(&iommu->lock, flags);}static void schizo_check_iommu_error(struct pci_controller_info *p,				     enum schizo_error_type type){	schizo_check_iommu_error_pbm(&p->pbm_A, type);	schizo_check_iommu_error_pbm(&p->pbm_B, type);}/* Uncorrectable ECC error status gathering. */#define SCHIZO_UE_AFSR	0x10030UL#define SCHIZO_UE_AFAR	0x10038UL#define SCHIZO_UEAFSR_PPIO	0x8000000000000000UL#define SCHIZO_UEAFSR_PDRD	0x4000000000000000UL#define SCHIZO_UEAFSR_PDWR	0x2000000000000000UL#define SCHIZO_UEAFSR_SPIO	0x1000000000000000UL#define SCHIZO_UEAFSR_SDMA	0x0800000000000000UL#define SCHIZO_UEAFSR_ERRPNDG	0x0300000000000000UL#define SCHIZO_UEAFSR_BMSK	0x000003ff00000000UL#define SCHIZO_UEAFSR_QOFF	0x00000000c0000000UL#define SCHIZO_UEAFSR_AID	0x000000001f000000UL#define SCHIZO_UEAFSR_PARTIAL	0x0000000000800000UL#define SCHIZO_UEAFSR_OWNEDIN	0x0000000000400000UL#define SCHIZO_UEAFSR_MTAGSYND	0x00000000000f0000UL#define SCHIZO_UEAFSR_MTAG	0x000000000000e000UL#define SCHIZO_UEAFSR_ECCSYND	0x00000000000001ffULstatic void schizo_ue_intr(int irq, void *dev_id, struct pt_regs *regs){	struct pci_controller_info *p = dev_id;	unsigned long afsr_reg = p->controller_regs + SCHIZO_UE_AFSR;	unsigned long afar_reg = p->controller_regs + SCHIZO_UE_AFAR;	unsigned long afsr, afar, error_bits;	int reported, limit;	/* Latch uncorrectable error status. */	afar = schizo_read(afar_reg);	/* If either of the error pending bits are set in the	 * AFSR, the error status is being actively updated by	 * the hardware and we must re-read to get a clean value.	 */	limit = 1000;	do {		afsr = schizo_read(afsr_reg);	} while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);	/* Clear the primary/secondary error status bits. */	error_bits = afsr &		(SCHIZO_UEAFSR_PPIO | SCHIZO_UEAFSR_PDRD | SCHIZO_UEAFSR_PDWR |		 SCHIZO_UEAFSR_SPIO | SCHIZO_UEAFSR_SDMA);	if (!error_bits)		return;	schizo_write(afsr_reg, error_bits);	/* Log the error. */	printk("SCHIZO%d: Uncorrectable Error, primary error type[%s]\n",	       p->index,	       (((error_bits & SCHIZO_UEAFSR_PPIO) ?		 "PIO" :		 ((error_bits & SCHIZO_UEAFSR_PDRD) ?		  "DMA Read" :		  ((error_bits & SCHIZO_UEAFSR_PDWR) ?		   "DMA Write" : "???")))));	printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n",	       p->index,	       (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,	       (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,	       (afsr & SCHIZO_UEAFSR_AID) >> 24UL);	printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n",	       p->index,	       (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,	       (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,	       (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,	       (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,	       (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);	printk("SCHIZO%d: UE AFAR [%016lx]\n", p->index, afar);	printk("SCHIZO%d: UE Secondary errors [", p->index);	reported = 0;	if (afsr & SCHIZO_UEAFSR_SPIO) {		reported++;		printk("(PIO)");	}	if (afsr & SCHIZO_UEAFSR_SDMA) {		reported++;		printk("(DMA)");	}	if (!reported)		printk("(none)");	printk("]\n");	/* Interrogate IOMMU for error status. */	schizo_check_iommu_error(p, UE_ERR);	schizo_clear_other_err_intr(irq);}#define SCHIZO_CE_AFSR	0x10040UL#define SCHIZO_CE_AFAR	0x10048UL#define SCHIZO_CEAFSR_PPIO	0x8000000000000000UL#define SCHIZO_CEAFSR_PDRD	0x4000000000000000UL#define SCHIZO_CEAFSR_PDWR	0x2000000000000000UL#define SCHIZO_CEAFSR_SPIO	0x1000000000000000UL#define SCHIZO_CEAFSR_SDMA	0x0800000000000000UL#define SCHIZO_CEAFSR_ERRPNDG	0x0300000000000000UL#define SCHIZO_CEAFSR_BMSK	0x000003ff00000000UL#define SCHIZO_CEAFSR_QOFF	0x00000000c0000000UL#define SCHIZO_CEAFSR_AID	0x000000001f000000UL#define SCHIZO_CEAFSR_PARTIAL	0x0000000000800000UL#define SCHIZO_CEAFSR_OWNEDIN	0x0000000000400000UL#define SCHIZO_CEAFSR_MTAGSYND	0x00000000000f0000UL#define SCHIZO_CEAFSR_MTAG	0x000000000000e000UL#define SCHIZO_CEAFSR_ECCSYND	0x00000000000001ffULstatic void schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs){	struct pci_controller_info *p = dev_id;	unsigned long afsr_reg = p->controller_regs + SCHIZO_CE_AFSR;	unsigned long afar_reg = p->controller_regs + SCHIZO_CE_AFAR;	unsigned long afsr, afar, error_bits;	int reported, limit;	/* Latch error status. */	afar = schizo_read(afar_reg);	/* If either of the error pending bits are set in the	 * AFSR, the error status is being actively updated by	 * the hardware and we must re-read to get a clean value.	 */	limit = 1000;	do {		afsr = schizo_read(afsr_reg);	} while ((afsr & SCHIZO_UEAFSR_ERRPNDG) != 0 && --limit);	/* Clear primary/secondary error status bits. */	error_bits = afsr &		(SCHIZO_CEAFSR_PPIO | SCHIZO_CEAFSR_PDRD | SCHIZO_CEAFSR_PDWR |		 SCHIZO_CEAFSR_SPIO | SCHIZO_CEAFSR_SDMA);	if (!error_bits)		return;	schizo_write(afsr_reg, error_bits);	/* Log the error. */	printk("SCHIZO%d: Correctable Error, primary error type[%s]\n",	       p->index,	       (((error_bits & SCHIZO_CEAFSR_PPIO) ?		 "PIO" :		 ((error_bits & SCHIZO_CEAFSR_PDRD) ?		  "DMA Read" :		  ((error_bits & SCHIZO_CEAFSR_PDWR) ?		   "DMA Write" : "???")))));	/* XXX Use syndrome and afar to print out module string just like	 * XXX UDB CE trap handler does... -DaveM	 */	printk("SCHIZO%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n",	       p->index,	       (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL,	       (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL,	       (afsr & SCHIZO_UEAFSR_AID) >> 24UL);	printk("SCHIZO%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n",	       p->index,	       (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0,	       (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0,	       (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL,	       (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL,	       (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL);	printk("SCHIZO%d: CE AFAR [%016lx]\n", p->index, afar);	printk("SCHIZO%d: CE Secondary errors [", p->index);	reported = 0;	if (afsr & SCHIZO_CEAFSR_SPIO) {		reported++;		printk("(PIO)");	}	if (afsr & SCHIZO_CEAFSR_SDMA) {		reported++;		printk("(DMA)");	}	if (!reported)		printk("(none)");	printk("]\n");	schizo_clear_other_err_intr(irq);}#define SCHIZO_PCI_AFSR	0x2010UL#define SCHIZO_PCI_AFAR	0x2018UL#define SCHIZO_PCIAFSR_PMA	0x8000000000000000UL#define SCHIZO_PCIAFSR_PTA	0x4000000000000000UL#define SCHIZO_PCIAFSR_PRTRY	0x2000000000000000UL#define SCHIZO_PCIAFSR_PPERR	0x1000000000000000UL#define SCHIZO_PCIAFSR_PTTO	0x0800000000000000UL#define SCHIZO_PCIAFSR_PUNUS	0x0400000000000000UL#define SCHIZO_PCIAFSR_SMA	0x0200000000000000UL#define SCHIZO_PCIAFSR_STA	0x0100000000000000UL#define SCHIZO_PCIAFSR_SRTRY	0x0080000000000000UL#define SCHIZO_PCIAFSR_SPERR	0x0040000000000000UL#define SCHIZO_PCIAFSR_STTO	0x0020000000000000UL#define SCHIZO_PCIAFSR_SUNUS	0x0010000000000000UL#define SCHIZO_PCIAFSR_BMSK	0x000003ff00000000UL#define SCHIZO_PCIAFSR_BLK	0x0000000080000000UL#define SCHIZO_PCIAFSR_CFG	0x0000000040000000UL#define SCHIZO_PCIAFSR_MEM	0x0000000020000000UL#define SCHIZO_PCIAFSR_IO	0x0000000010000000ULstatic void schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs){	struct pci_pbm_info *pbm = dev_id;	struct pci_controller_info *p = pbm->parent;	unsigned long afsr_reg, afar_reg, base;	unsigned long afsr, afar, error_bits;	int reported;	char pbm_name;	base = p->controller_regs;	if (pbm == &pbm->parent->pbm_A) {		base += SCHIZO_PBM_A_REGS_OFF;		pbm_name = 'A';	} else {		base += SCHIZO_PBM_B_REGS_OFF;		pbm_name = 'B';	}	afsr_reg = base + SCHIZO_PCI_AFSR;	afar_reg = base + SCHIZO_PCI_AFAR;	/* Latch error status. */	afar = schizo_read(afar_reg);	afsr = schizo_read(afsr_reg);	/* Clear primary/secondary error status bits. */	error_bits = afsr &		(SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA |		 SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR |		 SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS |		 SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA |		 SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |		 SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS);	if (!error_bits)		return;	schizo_write(afsr_reg, error_bits);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -