[comp.sys.sgi] Catching Buss Errors

chlebana@physics.utoronto.ca (Frank Chlebana) (05/15/91)

I am using the 4D/35S to read in data from memory in a remote VME crate
into local memory.

I need to protect against bus errors leading to a kernel PANIC, if someone 
resets the crate or snipped the cable to the remote VME crate.

Until now I was using a 4D/25S, and was able to prevent kernel PANICS.
Things have changed with the 4D/35S, and what I tried to piece together
from IP12.h does not work. Essentially I need to do the same thing as is
done in the routine badaddr, a routine which checks for bad address access.

How do I properly mask/restore interrupts so that I can prevent the kernel
PANIC, on the 4D/35S os 3.3.2?

Frank Chlebana
chlebana@oldkat.physics.utoronto.ca

The relevent c code wrapped around the transfer routine looks like

-8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----
prior = splhi();
private.p_nofault = 1;
if (cp_from_bb(kvaddr, k1virt, current_bc) 
   stat_error_code = BBERR_COPYFAULT;
private.p_nofault = 0;
splx(prior);
->8----->8----->8----->8----->8----->8----->8----->8----->8----->8----->8----

The following is the assembler code wrapped around the copy loop.

-8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<-----8<----
#ifdef IP12

#define SR_ILEVL9 0x00004800
#define LIO_0_IMASK 0x00
#define LIO_1_IMASK 0x80

/* save C0_SR in t2 LIO_0_MASK in t3 LIO_1_MASK in t4*/
#define maskintm \
	.set	noreorder ; \
	mfc0	t2,C0_SR ; \
	lwl	t3,LIO_0_MASK_ADDR|K1BASE ; \
	lwl	t4,LIO_1_MASK_ADDR|K1BASE ; \
	li	v0,LIO_0_IMASK ; \
	li	v1,LIO_1_IMASK ; \
	mtc0	zero,C0_SR ; \
	sb	v0,LIO_0_MASK_ADDR|K1BASE ; \
	li	v0,SR_IEC|SR_ILEVL9 ; \
	sb	v1,LIO_1_MASK_ADDR|K1BASE ; \
	mtc0	v0,C0_SR ; \
	.set	reorder

/* restore C0_SR from t2 LIO_0_MASK from t3 LIO_1_MASK from t4 */
#define restoreintm \
	.set	noreorder ; \
	mfc0	v0,C0_SR ; \
	mtc0	zero,C0_SR ; \
	lwl	v0,LIO_0_MASK_ADDR|K1BASE ; \
	swl	t3,LIO_0_MASK_ADDR|K1BASE ; \
	lwl	v0,LIO_1_MASK_ADDR|K1BASE ; \
	swl	t4,LIO_1_MASK_ADDR|K1BASE ; \
	mtc0	t2,C0_SR ; \
	.set	reorder

/* clear any pending bus errors */
#define	clearbuserrm	\
	lw	zero,PAR_CL_ADDR|K1BASE	
#endif   /* IP12 */

NESTED(cp_from_bb, BADADDRFRM, zero)
	.set	nomove
	subu	sp,BADADDRFRM
	sw	ra,BADADDRFRM-4(sp)

	maskintm 
	jal	cp_from_bb1 

	.set	noreorder
	mfc0	v0,C0_CAUSE
	nop	
	and	v0,CAUSE_IP8
	.set	reorder
	bne	v0,zero,bbfrerror

	restoreintm 
	lw	ra,BADADDRFRM-4(sp)
	addu	sp,BADADDRFRM
	move	v0,zero
	j	ra

	END(cp_from_bb)
	.set	move

NESTED(bbfrerror, BADADDRFRM, zero)
	.set	nomove
	clearbuserrm

	/* TODO remove this in production version */	
	PRINTF("cp_from_bb : bus error\n")            

	restoreintm 
	li	v0,BBERR_COPYFAULT

	lw	ra,BADADDRFRM-4(sp)
	addu	sp,BADADDRFRM

	j	ra
	END(bbfrerror)
	.set	move
->8----->8----->8----->8----->8----->8----->8----->8----->8----->8----->8----