arch/mips/dec/ecc-berr.c

Source file repositories/reference/linux-study-clean/arch/mips/dec/ecc-berr.c

File Facts

System
Linux kernel
Corpus path
arch/mips/dec/ecc-berr.c
Extension
.c
Size
7648 bytes
Lines
281
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!(syn & KN0X_ESR_VLDLO)) {
			/* Ack now, no rewrite will happen. */
			dec_ecc_be_ack();

			fmt = KERN_ALERT "%s" "invalid\n";
		} else {
			sngl = syn & KN0X_ESR_SNGLO;
			syn &= KN0X_ESR_SYNLO;

			/*
			 * Multibit errors may be tagged incorrectly;
			 * check the syndrome explicitly.
			 */
			for (i = 0; i < 25; i++)
				if (syn == data_mbit[i])
					break;

			if (i < 25) {
				status = mbestr;
			} else if (!sngl) {
				status = dbestr;
			} else {
				volatile u32 *ptr =
					(void *)CKSEG1ADDR(address);

				*ptr = *ptr;		/* Rewrite. */
				iob();

				status = sbestr;
				action = MIPS_BE_DISCARD;
			}

			/* Ack now, now we've rewritten (or not). */
			dec_ecc_be_ack();

			if (syn && syn == (syn & -syn)) {
				if (syn == 0x01) {
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at check bit C%s\n";
					xbit = "X";
				} else {
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at check bit C%s%u\n";
				}
				i = syn >> 2;
			} else {
				for (i = 0; i < 32; i++)
					if (syn == data_sbit[i])
						break;
				if (i < 32)
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error "
					      "at data bit D%s%u\n";
				else
					fmt = KERN_ALERT "%s"
					      "%#04x -- %s bit error\n";
			}
		}
	}

	if (action != MIPS_BE_FIXUP && __ratelimit(&rs)) {
		printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx\n",
			kind, agent, cycle, event, address);

		if (erraddr & KN0X_EAR_ECCERR)
			printk(fmt, "  ECC syndrome ", syn, status, xbit, i);
	}

	return action;
}

int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup)
{
	return dec_ecc_be_backend(regs, is_fixup, 0);
}

irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id)
{
	struct pt_regs *regs = get_irq_regs();

	int action = dec_ecc_be_backend(regs, 0, 1);

	if (action == MIPS_BE_DISCARD)
		return IRQ_HANDLED;

	/*
	 * FIXME: Find the affected processes and kill them, otherwise
	 * we must die.

Annotation

Implementation Notes