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

📄 cerr-sb1.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	0xC808099264FF0738ULL,	0x08099264FF0738C8ULL,	0x099264FF0738C808ULL,	0x9264FF0738C80809ULL,	0x64FF0738C8080992ULL,	0xFF0738C808099264ULL};/* Calculate the parity on a range of bits */static char range_parity(uint64_t dword, int max, int min){	char parity = 0;	int i;	dword >>= min;	for (i=max-min; i>=0; i--) {		if (dword & 0x1)			parity = !parity;		dword >>= 1;	}	return parity;}/* Calculate the 4-bit even byte-parity for an instruction */static unsigned char inst_parity(uint32_t word){	int i, j;	char parity = 0;	for (j=0; j<4; j++) {		char byte_parity = 0;		for (i=0; i<8; i++) {			if (word & 0x80000000)				byte_parity = !byte_parity;			word <<= 1;		}		parity <<= 1;		parity |= byte_parity;	}	return parity;}static uint32_t extract_ic(unsigned short addr, int data){	unsigned short way;	int valid;	uint32_t taghi, taglolo, taglohi;	unsigned long long taglo, va;	uint64_t tlo_tmp;	uint8_t lru;	int res = 0;	printk("Icache index 0x%04x  ", addr);	for (way = 0; way < 4; way++) {		/* Index-load-tag-I */		__asm__ __volatile__ (		"	.set	push		\n\t"		"	.set	noreorder	\n\t"		"	.set	mips64		\n\t"		"	.set	noat		\n\t"		"	cache	4, 0(%3)	\n\t"		"	mfc0	%0, $29		\n\t"		"	dmfc0	$1, $28		\n\t"		"	dsrl32	%1, $1, 0	\n\t"		"	sll	%2, $1, 0	\n\t"		"	.set	pop"		: "=r" (taghi), "=r" (taglohi), "=r" (taglolo)		: "r" ((way << 13) | addr));		taglo = ((unsigned long long)taglohi << 32) | taglolo;		if (way == 0) {			lru = (taghi >> 14) & 0xff;			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",				    ((addr >> 5) & 0x3), /* bank */				    ((addr >> 7) & 0x3f), /* index */				    (lru & 0x3),				    ((lru >> 2) & 0x3),				    ((lru >> 4) & 0x3),				    ((lru >> 6) & 0x3));		}		va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))			va |= 0x3FFFF00000000000ULL;		valid = ((taghi >> 29) & 1);		if (valid) {			tlo_tmp = taglo & 0xfff3ff;			if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {				printk("   ** bad parity in VTag0/G/ASID\n");				res |= CP0_CERRI_TAG_PARITY;			}			if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {				printk("   ** bad parity in R/VTag1\n");				res |= CP0_CERRI_TAG_PARITY;			}		}		if (valid ^ ((taghi >> 27) & 1)) {			printk("   ** bad parity for valid bit\n");			res |= CP0_CERRI_TAG_PARITY;		}		printk(" %d  [VA %016llx]  [Vld? %d]  raw tags: %08X-%016llX\n",			    way, va, valid, taghi, taglo);		if (data) {			uint32_t datahi, insta, instb;			uint8_t predecode;			int offset;			/* (hit all banks and ways) */			for (offset = 0; offset < 4; offset++) {				/* Index-load-data-I */				__asm__ __volatile__ (				"	.set	push\n\t"				"	.set	noreorder\n\t"				"	.set	mips64\n\t"				"	.set	noat\n\t"				"	cache	6, 0(%3)  \n\t"				"	mfc0	%0, $29, 1\n\t"				"	dmfc0  $1, $28, 1\n\t"				"	dsrl32 %1, $1, 0 \n\t"				"	sll    %2, $1, 0 \n\t"				"	.set	pop         \n"				: "=r" (datahi), "=r" (insta), "=r" (instb)				: "r" ((way << 13) | addr | (offset << 3)));				predecode = (datahi >> 8) & 0xff;				if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {					printk("   ** bad parity in predecode\n");					res |= CP0_CERRI_DATA_PARITY;				}				/* XXXKW should/could check predecode bits themselves */				if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {					printk("   ** bad parity in instruction a\n");					res |= CP0_CERRI_DATA_PARITY;				}				if ((datahi & 0xf) ^ inst_parity(instb)) {					printk("   ** bad parity in instruction b\n");					res |= CP0_CERRI_DATA_PARITY;				}				printk("  %05X-%08X%08X", datahi, insta, instb);			}			printk("\n");		}	}	return res;}/* Compute the ECC for a data doubleword */static uint8_t dc_ecc(uint64_t dword){	uint64_t t;	uint32_t w;	uint8_t  p;	int      i;	p = 0;	for (i = 7; i >= 0; i--)	{		p <<= 1;		t = dword & mask_72_64[i];		w = (uint32_t)(t >> 32);		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);		w = (uint32_t)(t & 0xFFFFFFFF);		p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]		      ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);	}	return p;}struct dc_state {	unsigned char val;	char *name;};static struct dc_state dc_states[] = {	{ 0x00, "INVALID" },	{ 0x0f, "COH-SHD" },	{ 0x13, "NCO-E-C" },	{ 0x19, "NCO-E-D" },	{ 0x16, "COH-E-C" },	{ 0x1c, "COH-E-D" },	{ 0xff, "*ERROR*" }};#define DC_TAG_VALID(state) \    (((state) == 0x0) || ((state) == 0xf) || ((state) == 0x13) || \     ((state) == 0x19) || ((state) == 0x16) || ((state) == 0x1c))static char *dc_state_str(unsigned char state){	struct dc_state *dsc = dc_states;	while (dsc->val != 0xff) {		if (dsc->val == state)			break;		dsc++;	}	return dsc->name;}static uint32_t extract_dc(unsigned short addr, int data){	int valid, way;	unsigned char state;	uint32_t taghi, taglolo, taglohi;	unsigned long long taglo, pa;	uint8_t ecc, lru;	int res = 0;	printk("Dcache index 0x%04x  ", addr);	for (way = 0; way < 4; way++) {		__asm__ __volatile__ (		"	.set	push\n\t"		"	.set	noreorder\n\t"		"	.set	mips64\n\t"		"	.set	noat\n\t"		"	cache	5, 0(%3)\n\t"	/* Index-load-tag-D */		"	mfc0	%0, $29, 2\n\t"		"	dmfc0	$1, $28, 2\n\t"		"	dsrl32	%1, $1, 0\n\t"		"	sll	%2, $1, 0\n\t"		"	.set	pop"		: "=r" (taghi), "=r" (taglohi), "=r" (taglolo)		: "r" ((way << 13) | addr));		taglo = ((unsigned long long)taglohi << 32) | taglolo;		pa = (taglo & 0xFFFFFFE000ULL) | addr;		if (way == 0) {			lru = (taghi >> 14) & 0xff;			printk("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",				    ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */				    ((addr >> 6) & 0x3f), /* index */				    (lru & 0x3),				    ((lru >> 2) & 0x3),				    ((lru >> 4) & 0x3),				    ((lru >> 6) & 0x3));		}		state = (taghi >> 25) & 0x1f;		valid = DC_TAG_VALID(state);		printk(" %d  [PA %010llx]  [state %s (%02x)]  raw tags: %08X-%016llX\n",			    way, pa, dc_state_str(state), state, taghi, taglo);		if (valid) {			if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {				printk("   ** bad parity in PTag1\n");				res |= CP0_CERRD_TAG_ADDRESS;			}			if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {				printk("   ** bad parity in PTag0\n");				res |= CP0_CERRD_TAG_ADDRESS;			}		} else {			res |= CP0_CERRD_TAG_STATE;		}		if (data) {			uint32_t datalohi, datalolo, datahi;			unsigned long long datalo;			int offset;			char bad_ecc = 0;			for (offset = 0; offset < 4; offset++) {				/* Index-load-data-D */				__asm__ __volatile__ (				"	.set	push\n\t"				"	.set	noreorder\n\t"				"	.set	mips64\n\t"				"	.set	noat\n\t"				"	cache	7, 0(%3)\n\t" /* Index-load-data-D */				"	mfc0	%0, $29, 3\n\t"				"	dmfc0	$1, $28, 3\n\t"				"	dsrl32	%1, $1, 0 \n\t"				"	sll	%2, $1, 0 \n\t"				"	.set	pop"				: "=r" (datahi), "=r" (datalohi), "=r" (datalolo)				: "r" ((way << 13) | addr | (offset << 3)));				datalo = ((unsigned long long)datalohi << 32) | datalolo;				ecc = dc_ecc(datalo);				if (ecc != datahi) {					int bits = 0;					bad_ecc |= 1 << (3-offset);					ecc ^= datahi;					while (ecc) {						if (ecc & 1) bits++;						ecc >>= 1;					}					res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;				}				printk("  %02X-%016llX", datahi, datalo);			}			printk("\n");			if (bad_ecc)				printk("  dwords w/ bad ECC: %d %d %d %d\n",				       !!(bad_ecc & 8), !!(bad_ecc & 4),				       !!(bad_ecc & 2), !!(bad_ecc & 1));		}	}	return res;}

⌨️ 快捷键说明

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