[9242] in Athena Bugs

home help back first fref pref prev next nref lref last post

RT ECC machine check

daemon@ATHENA.MIT.EDU (John Carr)
Wed Apr 29 12:48:06 1992

To: bugs@Athena.MIT.EDU
Date: Wed, 29 Apr 1992 12:47:25 EDT
From: John Carr <jfc@Athena.MIT.EDU>


This fix makes the RT kernel handle machine checks better.  For example, an
uncorrectable causes a panic instead of a hang, and correctable errors are
detected and the bad ECC replaced (so single bit errors are less likely to
grow into double bit errors).

There are some unrelated changes in these patches; this is a diff of my
kernel with the kernel in /source.  I removed most of the diffs that were
unrelated to the ECC fix but some remain because they affected the same
section of code.


*** /source/bsd-4.3/common/sys/ca/trap.c	Fri Jun 16 17:55:14 1989
--- trap.c	Wed Apr 29 11:45:28 1992
***************
*** 53,64 ****
  #define ILL_OP	(PCS_KNOWN+PCS_BAD_I)
  #define PRIV_OP	(PCS_KNOWN+PCS_PRIV_I)
  
! struct sysent sysent[];
! int nsysent;
  char *mcpcfmt = MCPCFMT;
  
  char *icsfmt = ICSFMT;
! int _csr;				  /* the csr contents after trap */
  					  /* just ICS without CS */
  int addupc_r15 = 1;			  /* if we should use r15 if iar isn't good */
  
--- 52,65 ----
  #define ILL_OP	(PCS_KNOWN+PCS_BAD_I)
  #define PRIV_OP	(PCS_KNOWN+PCS_PRIV_I)
  
! extern struct sysent sysent[];
! extern int nsysent;
  char *mcpcfmt = MCPCFMT;
  
  char *icsfmt = ICSFMT;
! extern int csr,ser;			  /* the csr, ser contents after trap,
! 					     set by locore  */
! extern int sear;
  					  /* just ICS without CS */
  int addupc_r15 = 1;			  /* if we should use r15 if iar isn't good */
  
***************
*** 99,109 ****
  		(trdebug & SHOW_TRAP_REGS) ? locr0 : (int *)0));
  
  	switch (mcs_pcs) {
  	default:
  		if (mcs_pcs & MCS_CHECK) {	/* machine check */
! 			if (mcs_pcs & USER) {	/* machine check in user mode */
! 				printf("machine check in user mode ...\n");
  				prstate("machine check", mcs_pcs, info, locr0[IAR], ics_cs, locr0);
  				klsreset();	/* reinitialize keyboard */
  				klswait();	/* and wait until done */
  				printf("keyboard init done.\n");
--- 108,148 ----
  		(trdebug & SHOW_TRAP_REGS) ? locr0 : (int *)0));
  
  	switch (mcs_pcs) {
+ 	case MCS_CHECK:
+ 	case MCS_CHECK+USER:
+ 		printf("Unidentified machine check ignored.\n");
+ 		return;
+ 	case MCS_PMUC_CK+MCS_CHECK:
+ 	case MCS_PMUC_CK+MCS_CHECK+USER:
+ 		printf("machine check: Processor Channel Check\n");
+ 		prstate("machine check", mcs_pcs, info, locr0[IAR],
+ 			ics_cs, locr0);
+ 		return;
  	default:
  		if (mcs_pcs & MCS_CHECK) {	/* machine check */
! 			if (mcs_pcs & USER)	/* machine check in user mode */
! 				printf("machine check in user mode\n");
! 			else
! 				printf("machine check\n");
  			prstate("machine check", mcs_pcs, info, locr0[IAR], ics_cs, locr0);
+ 			if ((csr & CSR_EPOW) && !(csr & CSR_OHOH)) {
+ 				printf("power fail warning\n");
+ 				/* Wait a moment to see if it is a real
+ 				   power failure. */
+ 				DELAY(100000);
+ 				return;
+ 			} else if (ser & (MMU_EX_ECC|MMU_EX_CORECC)) {
+ 				printf("Bad ECC at real address %x\n", sear);
+ 				if (ser & MMU_EX_ECC)
+ 				  panic("uncorrectable ECC error");
+ 				fixup_ecc(sear);
+ 				/* Now that the error has been corrected,
+ 				   re-enable interrupt on correctable ECC
+ 				   errors.  */
+ 				iow(MMUBASE + MMU_TCR,
+ 				    ior (MMUBASE + MMU_TCR) | MMU_ECC);
+ 				goto out;
+ 			} else if (mcs_pcs & USER) {
  				klsreset();	/* reinitialize keyboard */
  				klswait();	/* and wait until done */
  				printf("keyboard init done.\n");
***************
*** 118,123 ****
--- 157,164 ----
  				klsreset();	/* reinitialize keyboard */
  				spl0();		/* allow interrupts */
  				klswait();	/* and wait until done */
+ 				spl7();
+ 				panic("machine check");
  			}
  		} else if (mcs_pcs & USER) {
  			printf("trap: unknown trap (0x%b) in user mode\n",
***************
*** 576,583 ****
  	    info,"\20\1DATA\2PROTECTION\3TLB-SPECIFICATION\4PAGE-FAULT\5MULTIPLE\6EXTERNAL-DEVICE\7IPT-SPECIFICATION\10ROS-WRITE\12TLB-RELOAD\13CORRECTABLE-ECC",
  	    iar, ics_cs, icsfmt);
  #ifdef IBMRTPC
! 	csr_print(*(int volatile *)CSR);
! #endif IBMRTPC
  	if (regs) {
  		for (i=0; i<16; ) {
  			if ((i & 0x03) == 0)
--- 521,528 ----
  	    info,"\20\1DATA\2PROTECTION\3TLB-SPECIFICATION\4PAGE-FAULT\5MULTIPLE\6EXTERNAL-DEVICE\7IPT-SPECIFICATION\10ROS-WRITE\12TLB-RELOAD\13CORRECTABLE-ECC",
  	    iar, ics_cs, icsfmt);
  #ifdef IBMRTPC
! 	csr_print(csr);
! #endif
  	if (regs) {
  		for (i=0; i<16; ) {
  			if ((i & 0x03) == 0)
***************
*** 587,602 ****
  				printf("\n");
  		}
  #ifdef ROMPC
! 		if (cpu_model == CPU_ROMPC && regs[ECR_COUNT])
  			{
  			print_ecr(regs[ECR_COUNT], (int) &regs[EX1_CTL]);
  #define PRINT(value) if (regs[EX_/**/value]) printf("value=%x ",regs[EX_/**/value])
  			PRINT(GSR1);
  			PRINT(REP1);
  			PRINT(GSR2);
  			PRINT(REP2);
  			}
! #endif ROMPC
  	}
  	printser();
  }
--- 532,553 ----
  				printf("\n");
  		}
  #ifdef ROMPC
! 		if (cpu_model == CPU_ROMPC &&
! 		    (regs[ECR_COUNT] || (ser & (MMU_EX_CORECC|MMU_EX_ECC))))
  		  {
+ 		    if (regs[ECR_COUNT])
  		      print_ecr(regs[ECR_COUNT], (int) &regs[EX1_CTL]);
+ #ifdef __STDC__
+ #define PRINT(value) if (regs[EX_ ## value]) printf(#value "=%x ",regs[EX_ ## value])
+ #else
  #define PRINT(value) if (regs[EX_/**/value]) printf("value=%x ",regs[EX_/**/value])
+ #endif
  		    PRINT(GSR1);
  		    PRINT(REP1);
  		    PRINT(GSR2);
  		    PRINT(REP2);
  		  }
! #endif
  	}
  	printser();
  }
***************
*** 644,652 ****
  {
  #ifdef IBMRTPC
  	printf("CSR=%b\n", csr,
! 			"\20\11PIO-PENDING\12PLANAR-BUSY\13CH-RESET-CAPTURED\14DMA-EXECPTION\15I/O-CHECK\16INV-OPERATION\17PROT-VIOLATION\20PIO-DMA\21DMA-ERR-CH8\22DMA-ERR-CH7\23DMA-ERR-CH6\24DMA-ERR-CH5\25DMA-ERR-CH3\26DMA-ERR-CH2\27DMA-ERR-CH1\30DMA-ERR-CH0\31PIO-ERR\33SYSTEM-ATTN\34SOFT-RESET\35POWER\37INTR-PENDING\40EXCEPTION");
! 	_csr = csr;		/* save it for later */
! #endif IBMRTPC
  	}
  
  
--- 598,605 ----
  {
  #ifdef IBMRTPC
  	printf("CSR=%b\n", csr,
! 			"\20\11PIO-PENDING\12PLANAR-BUSY\13CH-RESET-CAPTURED\14DMA-EXCEPTION\15I/O-CHECK\16INV-OPERATION\17PROT-VIOLATION\20PIO-DMA\21DMA-ERR-CH8\22DMA-ERR-CH7\23DMA-ERR-CH6\24DMA-ERR-CH5\25DMA-ERR-CH3\26DMA-ERR-CH2\27DMA-ERR-CH1\30DMA-ERR-CH0\31PIO-ERR\33SYSTEM-ATTN\34SOFT-RESET\35POWER\37INTR-PENDING\40EXCEPTION");
! #endif
  	}
  
  
***************
*** 729,742 ****
  {
  /* cannot use MMU_IOBASE because it doesn't return a value (DUMB!) */
  	register int mmubase = MMUBASE; /* get base address */
! 	extern int ser;		/* use saved value from locore */
  	register int reg;
  
- /*	ser = ior((unsigned) mmubase + MMU_SER);	/* pick up the SER */
  	printf("SER=%b ", ser,
  	    "\20\1DATA\2PROTECTION\3TLB-SPECIFICATION\4PAGE-FAULT\5MULTIPLE\6EXTERNAL-DEVICE\7IPT-SPECIFICATION\10ROS-WRITE\12TLB-RELOAD\13CORRECTABLE-ECC\14STORAGE\15LOAD\16I/O-ADDRESS\17STORAGE-ADDRESS\20PMUC-NAKDN\21PMUC-NAKDA\22SEGMENT-VIOLATION");
! 	printf("SEAR=%x ", ior((unsigned) mmubase + MMU_SEAR));
  	printf("TRAR=%x ", ior((unsigned) mmubase + MMU_TRAR));
  	reg = ior((unsigned) mmubase + MMU_TCR);
  	printf("TCR=%b HAT/IPT=%x\n", reg,
  	    "\20\114K-PAGE\12RESERVED\13INTR-TLB-RELOAD\14INTR-CECC\15TLIPT\16RAS-DIAG\17ISPER\20V=R", reg & 0xff);
--- 694,707 ----
  {
  /* cannot use MMU_IOBASE because it doesn't return a value (DUMB!) */
  	register int mmubase = MMUBASE; /* get base address */
! 	extern int rmdr;		/* use saved value from locore */
  	register int reg;
  
  	printf("SER=%b ", ser,
  	    "\20\1DATA\2PROTECTION\3TLB-SPECIFICATION\4PAGE-FAULT\5MULTIPLE\6EXTERNAL-DEVICE\7IPT-SPECIFICATION\10ROS-WRITE\12TLB-RELOAD\13CORRECTABLE-ECC\14STORAGE\15LOAD\16I/O-ADDRESS\17STORAGE-ADDRESS\20PMUC-NAKDN\21PMUC-NAKDA\22SEGMENT-VIOLATION");
! 	printf("SEAR=%x ", sear);
  	printf("TRAR=%x ", ior((unsigned) mmubase + MMU_TRAR));
+ 	printf("RMDR=%x ", rmdr);
  	reg = ior((unsigned) mmubase + MMU_TCR);
  	printf("TCR=%b HAT/IPT=%x\n", reg,
  	    "\20\114K-PAGE\12RESERVED\13INTR-TLB-RELOAD\14INTR-CECC\15TLIPT\16RAS-DIAG\17ISPER\20V=R", reg & 0xff);
***************
*** 815,825 ****
  register short *iar;
  register int ics_cs;
  {
- #ifdef IBMRTPC
- 	register int csr = *(int *)CSR;
- #endif IBMRTPC
  	register int mcs_pcs = mfsr(SCR_MCSPCS);
- 	extern int ser;		/* saved ser */
  
  	ser = ior((unsigned) MMUBASE + MMU_SER);	/* pick up the SER */
  	iow((unsigned) MMUBASE + MMU_SER, 0);		/* clear the SER */
--- 780,786 ----
***************
*** 829,835 ****
  #ifdef IBMRTPC
  	if (csr & CSR_OHOH)
  		panic("IOCC/PMUC exception");
! #endif IBMRTPC
  	if (ser & MMU_EX_OHOH)
  		panic("MMU/PMUC level 2 interrupt");
  	else
--- 790,796 ----
  #ifdef IBMRTPC
  	if (csr & CSR_OHOH)
  		panic("IOCC/PMUC exception");
! #endif
  	if (ser & MMU_EX_OHOH)
  		panic("MMU/PMUC level 2 interrupt");
  	else
***************
*** 1014,1028 ****
  		 * the IOCC was the 2nd exception in the stack, and the first
  		 * exception was from a different channel or was an IOR
  		 */
! 			if ((_csr = *(int *)CSR) & 0x80000000) {
  			/*
  			 * bit 0 of the CSR is set indicating the IOCC reported
  			 * the program check.
  			 */
- 				* (int *) CSR = 0;	/* reset CSR */
  				DEBUGF(trdebug & SHOW_MUX2,{
  					printf("apc_mux: IOCC ");
! 					csr_print(_csr);
  					});
  			} else if (IS_STORE(ctl1) && !IS_STORE(ctl2) &&
  					(locr0[EX_GSR1] & IOIM_PARITY_REC) == 0){
--- 975,988 ----
  		 * the IOCC was the 2nd exception in the stack, and the first
  		 * exception was from a different channel or was an IOR
  		 */
! 			if (csr & CSR_EXREP) {
  			/*
  			 * bit 0 of the CSR is set indicating the IOCC reported
  			 * the program check.
  			 */
  				DEBUGF(trdebug & SHOW_MUX2,{
  					printf("apc_mux: IOCC ");
! 					csr_print(csr);
  					});
  			} else if (IS_STORE(ctl1) && !IS_STORE(ctl2) &&
  					(locr0[EX_GSR1] & IOIM_PARITY_REC) == 0){

*** /source/bsd-4.3/common/sys/ca/machdep.c	Thu Oct 26 01:31:58 1989
--- machdep.c	Wed Apr 29 11:48:01 1992
***************
*** 200,208 ****
  	 * check to see we have proper memory configuration 
  	 */
  	check_mem_config();
! #endif IBMRTPC
! #endif ROMPC
  
  	/*
  	 * Good {morning,afternoon,evening,night}.
  	 */
--- 191,202 ----
  	 * check to see we have proper memory configuration 
  	 */
  	check_mem_config();
! #endif
! #endif
  
+ 	/* Enable interrupt on correctable ECC error.  */
+ 	iow(MMUBASE + MMU_TCR, ior (MMUBASE + MMU_TCR) | MMU_ECC);
+ 
  	/*
  	 * Good {morning,afternoon,evening,night}.
  	 */
*** /source/bsd-4.3/common/sys/ca/lopckrt0.s	Thu Apr  7 13:11:18 1988
--- lopckrt0.s	Wed Apr 29 10:38:43 1992
***************
*** 55,62 ****
--- 55,69 ----
  	stm	r10,low_save10	# copy interrupt time rx into low_save var
  	mfs	scr_mcspcs,r10	# r10 = program check status
  	lps	1,pck_vec1	# get off program check level ASAP
+ 
+ 	.align	2
+ 
  pck1:
+ #if defined(ROMPC) && defined(SGP)
+ 	l	r12,_cpu_model
+ #endif
  	st	r1,low_save1      # copy interrupt time r1 into low_save var
+ 
  #ifdef DEBUG
  	lm	r14,pck_ps+old_iar# r14, r15 = iar, ics_cs at time of fault
  	l	r11,pck_ptr	# pick up trace pointer
***************
*** 68,82 ****
  	st	r12,pck_ptr	# store pointer
  #endif
  
  #ifdef ROMPC
          nilz  r12,r10,PCS_TRAP+PCS_PRIV_I+PCS_BAD_I+PCS_RESERVED
  #else
          nilz  r12,r10,PCS_UNKNOWN+PCS_TRAP+PCS_PRIV_I+PCS_BAD_I+PCS_RESERVED
  #endif
!         bnz   pck_notstg        # branch if any of those bad guys
  
-  #	cau   r15,(MMUBASE)>>16(r0) # i/o base address of MMU
-  #	oil   r15,r15,(MMUBASE)&0xffff
  	get	r15,$MMUBASE	# i/o base address of MMU
          ior   r14,MMU_SER(r15) # r14 = storage exception register
  	st	r14,_ser	# save ser
--- 75,90 ----
  	st	r12,pck_ptr	# store pointer
  #endif
  
+ 	nilz	r12,r10,0xff00	# machine check?
+ 	bne	pck_double_fault
+ 
  #ifdef ROMPC
  	nilz  r12,r10,PCS_TRAP+PCS_PRIV_I+PCS_BAD_I+PCS_RESERVED
  #else
  	nilz  r12,r10,PCS_UNKNOWN+PCS_TRAP+PCS_PRIV_I+PCS_BAD_I+PCS_RESERVED
  #endif
! 	jnz	pck_notstg	# branch if any of those bad guys
  
  	get	r15,$MMUBASE	# i/o base address of MMU
          ior	r14,MMU_SER(r15) # r14 = storage exception register
  	st	r14,_ser	# save ser
***************
*** 83,91 ****
  #ifdef DEBUG
  	st	r14,8(r11)	# save instead of sp
  #endif
          niuo  r13,r14,MMU_EX_OHOH_UPPER  # unexpected upper bits
          nilo  r13,r13,MMU_EX_OHOH_LOWER  # unexpected lower bits
!         bnz   pck_debug          # branch if any unexpected bits are on
  
      # Following added by mjb to deal with lm and stm data faults.
      # Maybe I even got it right this time.
--- 91,103 ----
  #ifdef DEBUG
  	st	r14,8(r11)	# save instead of sp
  #endif
+ 
+ 	nilz	r13,r14,MMU_EX_ECC|MMU_EX_CORECC
+ 	jnz	pck_ecc_fault
+ 
  	niuo	r13,r14,MMU_EX_OHOH_UPPER	# unexpected upper bits
          nilo	r13,r13,MMU_EX_OHOH_LOWER	# unexpected lower bits
! 	jnz	pck_debug		# branch if any unexpected bits are on
  
      # Following added by mjb to deal with lm and stm data faults.
      # Maybe I even got it right this time.
***************
*** 93,99 ****
  	nilz  r13,r14,MMU_EX_MULTX  # Multiple exceptions indicated?
  	jz    pck05		# Nope.
          mttbil r10,30-16        # d-fetch vs i-fetch bit
!         bntb  pck_debug          # jump if i-fetch -- this is not normal
  	nilo  r14,r14,0xFFFF-MMU_EX_MULTX # Let's not get confused
  pck05:
      # End of lines added by mjb to deal with lm and stm exceptions.
--- 105,111 ----
  	nilz	r13,r14,MMU_EX_MULTX  # Multiple exceptions indicated?
  	jz	pck05		# Nope.
          mttbil	r10,30-16        # d-fetch vs i-fetch bit
! 	jntb	pck_debug          # jump if i-fetch -- this is not normal
  	nilo	r14,r14,0xFFFF-MMU_EX_MULTX # Let's not get confused
  pck05:
      # End of lines added by mjb to deal with lm and stm exceptions.
***************
*** 115,129 ****
          jl    pck10             # then jump (lower page faulted)
          ais   r12,6             # else put iar into higher page
  pck10:
-  #***    nilo  r12,0-PAGESIZE    | zero page offset bits in exception address
          nilo  r12,r12,0-PAGESIZE    # zero page offset bits in exception address
          nilz  r11,r14,PAGESIZE-1# zero all but page offset bits in exception reg
          o     r11,r12           # fold interesting exception bits into pg offset
! 	s	r14,r14		# zippo
  	iow   r14,MMU_SER(r15) # Clear the exception register
  	get	r14,$SEAR_VALUE # get value to reset SEAR
  	iow   r14,MMU_SEAR(r15) # set the exception address register
!         b     pck_fault         # go handle page fault
   #
   #  program check, but not a storage fault
   #  if debugger present and in kernel mode pass to the debugger
--- 127,142 ----
          jl	pck10             # then jump (lower page faulted)
          ais	r12,6             # else put iar into higher page
  pck10:
  	nilo	r12,r12,0-PAGESIZE # zero page offset bits in exception address
  	nilz	r11,r14,PAGESIZE-1# zero all but page offset bits in exception reg
  	o	r11,r12		# fold interesting exception bits into pg offset
! 	lis	r14,0
  	iow	r14,MMU_SER(r15) # Clear the exception register
  	get	r14,$SEAR_VALUE # get value to reset SEAR
  	iow	r14,MMU_SEAR(r15) # set the exception address register
! 
! 	j	pck_real
! 
   #
   #  program check, but not a storage fault
   #  if debugger present and in kernel mode pass to the debugger
***************
*** 136,155 ****
  	jntb	pck_debug	#transfer control to debugger if not user mode
  #endif
           mttbil r10,26-16        # if not a trap inst (bit 26 from PCS)
!          jntb  pck_real          # then jump
  	 get   r10,$(BKPT)	#  mcs_pcs value for breakpoint inst "check"
   #
   #  real program checks - call fault to handle
   #
  pck_real:
! 	lis r11,0             # no additional information required
  	b	pck_fault	# handle as a fault
   #
   # pass control to debugger if it is present
   #
  pck_debug:
  #ifndef RDB
! 	j	pck_real
  #endif
          mts   scr_mcspcs,r10    # r10 = program check status
  	bx	pck_jump_to_dan	# too bad no cnop's
--- 150,195 ----
  	jntb	pck_debug	#transfer control to debugger if not user mode
  #endif
          mttbil	r10,26-16		# if not a trap inst (bit 26 from PCS)
!         bntbx	pck_real		# then jump
! 	lis	r11,0
  	get	r10,$(BKPT)	#  mcs_pcs value for breakpoint inst "check"
   #
   #  real program checks - call fault to handle
   #
  pck_real:
! 
! 	# Save and reset the CSR.  It is possible for the IOIM to be locked,
! 	# so read the IOIM1 GSR first.
! #ifdef ROMPC
! #ifdef SGP
! 	l	r12,_cpu
! 	cis	r12,CPU_SGP
! 	jeq	0f
! #endif
! 	cau	r12,IOIM1/UPPER(r0)	# get IOIM 1 base
! 	ior	r13,IOIM_REPLY(r12)	# get reply 
! 	st	r13,_ioim1_reply	# store IOIM1 reply 
! 	ior	r13,IOIM_GSR(r12)	# get status
! 	st	r13,_ioim1_gsr		# store IOIM1 GSR 
! 0:
! #endif
! 
! 	load	r12,CSR
! 	lis	r13,0
! 	store	r13,CSR,r14		# reset CSR
! 	st	r12,_csr
! 
  	b	pck_fault	# handle as a fault
+ 
   #
   # pass control to debugger if it is present
   #
+ 	.align	2
+ 
  pck_debug:
  #ifndef RDB
! 	bx	pck_real
! 	lis	r11,0
  #endif
  	mts	scr_mcspcs,r10	# r10 = program check status
  	bx	pck_jump_to_dan	# too bad no cnop's
***************
*** 156,158 ****
--- 196,259 ----
  	lm	r10,low_save10	# restore regs
  	.align	2		# align it 
  pck_jump_to_dan: b real0	# jump to original owner of program check
+ 
+ pck_double_fault:
+ 	get	r15,$MMUBASE
+ 	ior	r14,MMU_SER(r15)
+ 	st	r14,_ser
+ 	lis	r13,0
+ 	iow	r13,MMU_SER(r15)
+ 
+ pck_ecc_fault:
+ 	# r14 = SER, r15 has MMU base address
+ 	ior	r12,MMU_RMDR(r15)	# read the MMU RAS Mode Diagnostic
+ 					# Register to unlock the SEAR
+ 	st	r12,_rmdr
+ 	ior	r13,MMU_SEAR(r15)
+ 	st	r13,_sear
+ 
+ 	ior	r13,MMU_TCR(r15)
+ 	nilo	r13,r13,~(MMU_RAS+MMU_ECC)
+ 	iow	r13,MMU_TCR(r15)
+ 
+ #ifdef RDB
+ 	j	pck_debug
+ #endif
+ 
+ 	nilz	r11,r14,MMU_EX_ECC+MMU_EX_CORECC
+ 	beqx	pck_real
+ 	lis	r11,0
+ 
+ 	nilo	r11,r13,-PAGESIZE	# page address
+ 	nilz	r14,r14,PAGESIZE-1	# exception bits
+ 	o	r11,r14
+ 	lis	r14,0
+ 	iow	r14,MMU_SER(r15)
+ 	iow	r14,MMU_SEAR(r15)
+ 
+ 	l	r14,pck_ps+old_ics_cs
+ 	mttbiu	r14,PROBSTATE-16
+ 	btbx	pck_real
+ 	oi	r10,r10,MCS_CHECK	# make sure the machine check bit is
+ 					# on so no recovery is attempted
+ 
+ 	# ECC machine check in kernel mode.  Make sure the MMU has kernel
+ 	# mode map registers.
+ 
+ 	ior	r14,14(r15)
+ 	ior	r13,1(r15)
+ 	clrbl	r14,15
+ 	clrbl	r13,15
+ 	iow	r14,14(r15)
+ 	iow	r13,1(r15)
+ #ifdef ATR
+ 	ior	r14,MMU_IO_SEG(r15)
+ 	clrbl	r14,15
+ 	iow	r14,MMU_IO_SEG(r15)
+ #endif
+ 	ior	r14,0(r15)
+ 	clrbl	r14,15
+ 	iow	r14,0(r15)
+ 
+ 	b	pck_real
+ 
*** /source/bsd-4.3/common/sys/ca/lointr.s	Thu Apr  7 13:11:16 1988
--- lointr.s	Wed Apr 29 10:59:28 1992
***************
*** 159,169 ****
  
  	l	r10,_current_512_w
  	st	r10,XIH_PCIF512(r6)
! #endif ATR
  
! 	# Get the old IAR and ICS/CS
  	l	r10,LV2
  	l	r11,LV2+old_ics_cs
  
  	# Check if in Supervisor state and set Kernel stack
  
--- 158,187 ----
  
  	l	r10,_current_512_w
  	st	r10,XIH_PCIF512(r6)
! #endif
  
! #ifdef ROMPC
! #ifdef SGP
! 	l	r12,_cpu_model
! 	cis	r12,CPU_SGP
! 	jeq	0f
! #endif
! 	cau	r12,IOIM1/UPPER(r0)	# get IOIM 1 base
! 	ior	r13,IOIM_REPLY(r12)	# get reply 
! 	st	r13,_ioim1_reply	# store IOIM1 reply 
! 	ior	r13,IOIM_GSR(r12)	# get status
! 	st	r13,_ioim1_gsr		# store IOIM1 GSR 
! 0:
! #endif /* ROMPC */
! 
! 	# Get the old IAR and ICS/CS and save the CSR (a level 2
! 	# interrupt can be caused by an I/O error)
! 	load	r12,CSR
  	l	r10,LV2
  	l	r11,LV2+old_ics_cs
+ 	st	r12,_csr
+ 	lis	r12,0
+ 	store	r12,CSR,r13
  
  	# Check if in Supervisor state and set Kernel stack
  
***************
*** 345,355 ****
--- 363,444 ----
  	st    r1,low_save1      # copy interrupt time r1 into low_save var
  	stm   r10,low_save10    # copy interrupt time rx into low_save var
  
+ 	get	r15,$MMUBASE
+ 
+ 
+ 	ior	r13,MMU_TCR(r15)
+ 	nilo	r13,r13,~(MMU_RAS+MMU_ECC)
+ 	iow	r13,MMU_TCR(r15)
+ 
+ 	ior	r14,MMU_RMDR(r15)	# read the MMU RAS Mode Diagnostic
+ 					# Register to unlock the SEAR
+ 	st	r14,_rmdr
+ 	lis	r14,0
+ 	iow	r14,MMU_RMDR(r15)
+ 	ior	r14,MMU_SEAR(r15)
+ 	st	r14,_sear
+ 
  	mfs	scr_mcspcs,r10    # r10 = program check status
  	oi	r10,r10,MCS_CHECK # fake the machine check status
+ 	nilz	r11,r10,0xff	# also a program check?
+ 	jne	1f
+ 
+ #ifdef ROMPC
+ #ifdef SGP
+ 	l	r12,_cpu_model
+ 	cis	r12,CPU_SGP
+ 	jeq	0f
+ #endif
+ 	cau	r12,IOIM1/UPPER(r0)	# get IOIM 1 base
+ 	ior	r13,IOIM_REPLY(r12)	# get reply 
+ 	st	r13,_ioim1_reply	# store IOIM1 reply 
+ 	ior	r13,IOIM_GSR(r12)	# get status
+ 	st	r13,_ioim1_gsr		# store IOIM1 GSR 
+ 0:
+ #endif /* ROMPC */
+ 
+ 	load	r12,CSR
+ 	lis	r13,0
+ 	store	r13,CSR,r14		# reset CSR
+ 	st	r12,_csr
+ 
  	lps	1,mck_vec1	# get off machine check level ASAP
+ 
+ 	.align	2
+ 1:
+ 	cal	r13,double_fault
+ 	st	r13,mck_ps+old_iar	# call double_fault instead of pck0
+ 	lps	1,mck_ps		# back to program check level
+ 
+ 	.align	2
+ 
+ double_fault:
+ 	lps	1,pck_vec1		# normal program check handling
+ 
+ 
  mck1:
  
+ 	get	r15,$MMUBASE
+ 	ior	r14,MMU_SER(r15)
+ 	st	r14,_ser
+ 	lis	r11,0
+ 	iow	r11,MMU_SER(r15)
+ 	get	r11,$SEAR_VALUE
+ 	iow	r11,MMU_SEAR(r15)
+ 	#iow	r11,0x80(r15)		# MMU_INV_TLB
+ 
+ 	nilz	r11,r14,MMU_EX_ECC+MMU_EX_CORECC
+ 	jeq	mck_notstg
+ 
+ 	l	r11,_sear
+ 	nilz	r14,r14,PAGESIZE-1
+ 	nilo	r11,r11,-PAGESIZE
+ 	o	r11,r14
+ 	l	r12,mck_ps+old_iar	# get interrupt time iar
+ 	bx	mck_fault		# handle as a fault
+ 	l	r13,mck_ps+old_ics_cs	# get interrupt time ics and cs
+ 
+ 
   #
   #  machine check
   #  if LORDB and debugger present and in kernel mode pass to the debugger
***************
*** 362,374 ****
  	jntb	mck_debug	#transfer control to debugger if not user mode
  #endif
   #
!  #  real macine checks - call fault to handle
   #
  mck_real:
  	lis r11,0             # no additional information required
  	l     r12,mck_ps+old_iar     # get interrupt time iar
  	l     r13,mck_ps+old_ics_cs  # get interrupt time ics and cs
! 	b	mck_fault	# handle as a fault
  
  	.align	2
   #
--- 451,464 ----
  	jntb	mck_debug	#transfer control to debugger if not user mode
  #endif
   #
!  #  real machine checks - call fault to handle
   #
  mck_real:
  	lis	r11,0			# no additional information required
  	l	r12,mck_ps+old_iar	# get interrupt time iar
+ 	bx	mck_fault		# handle as a fault
  	l	r13,mck_ps+old_ics_cs	# get interrupt time ics and cs
! 
  
  	.align	2
   #
***************
*** 425,432 ****
  #endif FAST_INTERRUPTS
  
  	l	r0,iosave6		# Get The real value of R6 at IRPT
- 	sts	r0,XIHR6(r6)		# Save it on INT Stack
  	mfs	scr_mq,r9		# r9 = get mq at IRPT
  
  	#
  	# Get ready to call SLIH
--- 515,522 ----
  #endif FAST_INTERRUPTS
  
  	l	r0,iosave6		# Get The real value of R6 at IRPT
  	mfs	scr_mq,r9		# r9 = get mq at IRPT
+ 	sts	r0,XIHR6(r6)		# Save it on INT Stack
  
  	#
  	# Get ready to call SLIH
***************
*** 440,445 ****
--- 530,537 ----
   # interrupts can (and will) happen between here and 'afterslih'
   # note that translation is now ON.
   #
+ 
+ 	.align	2
  callslih:
  
  
*** /source/bsd-4.3/common/sys/ca/locore.c	Sun Jan 15 08:38:09 1989
--- locore.c	Wed Apr 29 12:21:10 1992
***************
*** 214,219 ****
--- 214,220 ----
  	.globl	_cnt
  	.globl	_ser
  	.globl	_sear
+ 	.globl	_rmdr
  #ifdef ATR
  	.globl _mem_size
  	.globl _pcif_base
***************
*** 313,318 ****
--- 314,320 ----
  #endif	/* ROMPC */
  _ser:		.long	0		# SER from last trap
  _sear:		.long	0		# SEAR from last trap
+ _rmdr:		.long	0
  #ifdef ATR
   # For the ATR version of the system we leave it to the PC to simulate
   # the memory configuration register on the RT. We do this by defining
***************
*** 426,431 ****
--- 428,440 ----
  #endif
  flipsave   :.long 0,0,0,0       # save for flipmode subroutine
  
+ 	.globl	_csr
+ 	.globl	_ioim1_gsr
+ 	.globl	_ioim1_reply
+ _csr:		.long	0	# copy of CSR after pck or level 2 interrupt
+ _ioim1_gsr:	.long	0
+ _ioim1_reply:	.long	0
+ 
   # Signal trampoline code
  sigcode: svc   139(r0)              # template moved to u area for signals
  
***************
*** 853,860 ****
   #          low_save1,low_save15, and low_ps are set
   #	   r0, r2 ... r14 have the required final values (lm already done)
  eye_catcher(go):
! 	 get	sp,$(USTRUCT+PCB_ICSCS) # sp-> icscs field of pcb
!          ls    sp,0(sp)             # sp = icscs field of pcb
           mfs   scr_iar,r15          # use r15 as base register
  1:	 .using 1b,r15              # tell assembler r15 is base register
           lps   0,realgo_ps          # turn off translation, interrupts off
--- 875,881 ----
   #          low_save1,low_save15, and low_ps are set
   #	   r0, r2 ... r14 have the required final values (lm already done)
  eye_catcher(go):
! 	load	sp,USTRUCT+PCB_ICSCS	# sp = icscs field of pcb
  	mfs	scr_iar,r15		# use r15 as base register
  1:	.using	1b,r15			# tell assembler r15 is base register
  	lps	0,realgo_ps		# turn off translation, interrupts off
***************
*** 892,904 ****
           l     r15,low_save15       # restore old r15
           lps   0,low_ps             # reload old ps, immediate interrupts ok
  go_ast:
- 	 get	sp,$KERNSTACK # switch to kernal stack
           l     r15,low_save15       # restore old r15
           stm   r10,low_save10       # assure low_save1 and low_save10 thru 15
- 	 get	r10,$VAST		# mcs_pcs value for VAX AST
-          x     r11,r11              # no more info needed
           l     r12,low_ps+old_iar   # retieve old iar
           l     r13,low_ps+old_ics_cs# retieve old ics_cs
           lps   0,fault_ps           # short circuit interrupt, handle fault
  1:       .using 1b
  #ifdef ROMPC
--- 913,925 ----
  	l     r15,low_save15       # restore old r15
  	lps   0,low_ps             # reload old ps, immediate interrupts ok
  go_ast:
  	l	r15,low_save15		# restore old r15
+ 	get	sp,$KERNSTACK		# switch to kernal stack
  	stm	r10,low_save10		# assure low_save1 and low_save10 thru 15
  	l	r12,low_ps+old_iar	# retieve old iar
  	l	r13,low_ps+old_ics_cs	# retieve old ics_cs
+ 	get	r10,$VAST		# mcs_pcs value for VAX AST
+ 	lis	r11,0			# no more info needed
  	lps   0,fault_ps           # short circuit interrupt, handle fault
  1:       .using 1b
  #ifdef ROMPC
***************
*** 910,917 ****
   #          low_save1,low_save15, and low_ps are set
   #	   r0, r2 ... r14 have the required final values (lm already done)
  eye_catcher(go2):
! 	 get	sp,$(USTRUCT+PCB_ICSCS) # sp-> icscs field of pcb
!          ls    sp,0(sp)             # sp = icscs field of pcb
           mfs   scr_iar,r15          # use r15 as base register
  1:	 .using 1b,r15              # tell assembler r15 is base register
           lps   0,realgo2_ps          # turn off translation, interrupts off
--- 931,937 ----
   #          low_save1,low_save15, and low_ps are set
   #	   r0, r2 ... r14 have the required final values (lm already done)
  eye_catcher(go2):
! 	load	sp,USTRUCT+PCB_ICSCS	# sp = icscs field of pcb
  	mfs	scr_iar,r15		# use r15 as base register
  1:	 .using 1b,r15			# tell assembler r15 is base register
  	lps	0,realgo2_ps		# turn off translation, interrupts off
***************
*** 945,957 ****
           l     r15,low_save15       # restore old r15
           lps   2,low_ps             # reload old ps, immediate interrupts ok
  go2_ast:
- 	 get	sp,$KERNSTACK # switch to kernal stack
           l     r15,low_save15       # restore old r15
           stm   r10,low_save10       # assure low_save1 and low_save10 thru 15
- 	 get	r10,$VAST		# mcs_pcs value for VAX AST
-          x     r11,r11              # no more info needed
           l     r12,low_ps+old_iar   # retieve old iar
           l     r13,low_ps+old_ics_cs# retieve old ics_cs
           lps   0,fault_ps           # short circuit interrupt, handle fault
  1:       .using 1b
  #endif ROMPC
--- 965,977 ----
  	l     r15,low_save15       # restore old r15
  	lps   2,low_ps             # reload old ps, immediate interrupts ok
  go2_ast:
  	l	r15,low_save15	# restore old r15
+ 	get	sp,$KERNSTACK	# switch to kernal stack
  	stm	r10,low_save10  # assure low_save1 and low_save10 thru 15
  	l	r12,low_ps+old_iar	# retieve old iar
  	l	r13,low_ps+old_ics_cs	# retieve old ics_cs
+ 	get	r10,$VAST	# mcs_pcs value for VAX AST
+ 	lis	r11,0		# no more info needed
  	lps	0,fault_ps	# short circuit interrupt, handle fault
  1:       .using 1b
  #endif ROMPC
***************
*** 1141,1156 ****
  	jeq	1f		# nope (NOTE: CPU_SGP == 0)
  #endif SGP
  #ifndef ATR
!  # read the IOIM1 and IOIM2 General Status registers to allow use of IOIM1 & 2
!  # we do this in all cases (even when the exceptions may not be in 
!  # segment F because it is faster to do the IORs than to do the conditional
!  # branches).
! 	cau	r12,IOIM1/UPPER(r0)	# get IOIM 1 base
! 	ior	r13,IOIM_REPLY(r12)	# get reply 
! 	st	r13,FAULT_REP1(sp)	# store IOIM1 reply 
! 	ior	r13,IOIM_GSR(r12)	# get status
! 	st	r13,FAULT_GSR1(sp)	# store IOIM1 GSR 
! #endif ATR
   # get IOIM2 reply and GSR
  #if	(defined(ATR) || defined(MOD135))
  	load	r12,_ioim2		# test if IOIM 2 present
--- 1160,1171 ----
  	jeq	1f		# nope (NOTE: CPU_SGP == 0)
  #endif SGP
  #ifndef ATR
!  # restore IOIM status saved in pck1
! 	l	r12,_ioim1_gsr
! 	l	r13,_ioim1_reply
! 	st	r12,FAULT_GSR1(sp)
! 	st	r13,FAULT_REP1(sp)
! #endif
   # get IOIM2 reply and GSR
  #if	(defined(ATR) || defined(MOD135))
  	load	r12,_ioim2		# test if IOIM 2 present
***************
*** 1202,1212 ****
   #  call trap() to handle the fault
   #
  fault_call_c:
-          clrsb scr_ics,INTMASK-16# enable interrupts now
   	   l    r13,__trap	 # store constant pointer
  	   ls	 r15,0(r13)	 # get address of routine
-          balrx r15,r15        # call trap
  		 mr r0,r13
   #
   #  restore complete context and return
   #
--- 1217,1227 ----
   #  call trap() to handle the fault
   #
  fault_call_c:
  	l	r13,__trap	# store constant pointer
  	ls	r15,0(r13)	# get address of routine
  	mr	r0,r13
+ 	balrx	r15,r15		# call trap
+ 	clrsb	scr_ics,INTMASK-16# enable interrupts now
   #
   #  restore complete context and return
   #
***************
*** 1216,1224 ****
           stm   r14,low_ps        # save in low core
           l     r15,FAULT_MQ(sp)  # get old multiplier/quotient (UNCHANGED)
           mts   scr_mq,r15        # restore multiplier/quotient
!          ls    r15,FAULT_R1(sp)  # get old r1 value (UNCHANGED)
!          st    r15,low_save1     # save in low core for go
!          l     r15,FAULT_R15(sp) # get old r15 value (UNCHANGED)
           st    r15,low_save15    # save in low core for go
           l     r0,FAULT_R0(sp)   # restore 0 (UNCHANGED)
  #ifdef ROMPC
--- 1231,1239 ----
  	stm	r14,low_ps		# save in low core
  	l	r15,FAULT_MQ(sp)	# get old multiplier/quotient (UNCHANGED)
  	mts	scr_mq,r15		# restore multiplier/quotient
! 	ls	r14,FAULT_R1(sp)	# get old r1 value (UNCHANGED)
! 	ls	r15,FAULT_R15(sp)	# get old r15 value (UNCHANGED)
! 	st	r14,low_save1		# save in low core for go
  	st	r15,low_save15		# save in low core for go
  	l	r0,FAULT_R0(sp)		# restore 0 (UNCHANGED)
  #ifdef ROMPC
***************
*** 1279,1302 ****
  
  	 get	r15,$UAREA	# address of 1st byte of kernel stack
           cl    sp,r15            # if kernel stack invalid
!          bl    pck_badsp          # then jump
  	 get   r15,$KERNSTACK	# address of last byte of kernel stack
           cl    sp,r15            # if kernel stack invalid
!          bh    pck_badsp          # then jump
!          cal16 r15,faultstm      # this inst catches bad kernel segments
           cl    r12,r15           # if fault anywhere else
           jne   goto_fault        # then jump
!          ai    sp,sp,FAULTSAVE      # undo subi before faultstm
!          b     pck_badsp          # deep trouble
  
  
  user_fault:
!          bali  sp,flipmode       # switch to kernel mode
  	get	sp,$KERNSTACK		# switch to kernel stack
  goto_fault:
  #ifdef RDB
  	cas	r15,r12,r0	# get iar into r15 for traceback
! #endif RDB
           lps   0,fault_ps        # goto fault: translation on, interrupts off
  
   #
--- 1294,1333 ----
  
  	get	r15,$UAREA		# address of 1st byte of kernel stack
  	cl	sp,r15			# if kernel stack invalid
! 	jl	pck_badsp		# then jump
  	get	r15,$KERNSTACK		# address of last byte of kernel stack
  	cl	sp,r15			# if kernel stack invalid
! 	jh	pck_stack_overflow	# then jump
! 	cal	r15,faultstm		# this inst catches bad kernel segments
! 	oiu	r15,r15,0xe000
  	cl	r12,r15			# if fault anywhere else
  	jne	goto_fault		# then jump
! 	j	pck_badseg		# deep trouble
  
+ 	.align	2
  
  user_fault:
! 	# unconditionally set kernel mode.  r14 and r15 are scratch registers.
! 	get	r15,$MMU_SEGREG0
! 	ior	r14,14(r15)
! 	ior	r1,1(r15)
! 	clrbl	r14,15
! 	clrbl	r1,15
! 	iow	r14,14(r15)
! 	iow	r1,1(r15)
! #ifdef ATR
! 	ior	r14,MMU_IO_SEG(r15)
! 	clrbl	r14,15
! 	iow	r14,MMU_IO_SEG(r15)
! #endif
! 	ior	r14,0(r15)
! 	clrbl	r14,15
! 	iow	r14,0(r15)
  	get	sp,$KERNSTACK	# switch to kernel stack
  goto_fault:
  #ifdef RDB
  	cas	r15,r12,r0	# get iar into r15 for traceback
! #endif
  	lps	0,fault_ps        # goto fault: translation on, interrupts off
  
   #
***************
*** 1320,1327 ****
  #ifdef RDB
  	tsh	r0,_badsp-real0(r0)	# test if already been here
  	ti	5,r0,0		# trap if not equal to zero
! #endif RDB
! 	j	goto_fault	# and goto fault for eventual panic
  
  
  1:       .using 1b               # tell assembler no base register
--- 1351,1381 ----
  #ifdef RDB
  	tsh	r0,_badsp-real0(r0)	# test if already been here
  	ti	5,r0,0		# trap if not equal to zero
! #endif
! 0:	wait
! 	j	0b		# lose
! 
! pck_badseg:
! 	get	sp,$KERNSTACK
! 	balix	r5,display
! 	cal	r2,0x95(r0)
! #ifdef RDB
! 	tsh	r0,_badsp-real0(r0)	# test if already been here
! 	ti	5,r0,0		# trap if not equal to zero
! #endif
! 0:	wait			# lose big
! 	j	0b
! 
! pck_stack_overflow:
! 	get	sp,$KERNSTACK
! 	balix	r5,display
! 	cal	r2,0x93(r0)
! #ifdef RDB
! 	tsh	r0,_badsp-real0(r0)
! 	ti	5,r0,0
! #endif
! 	j	goto_fault	# goto fault for eventual panic
! 
  
  
  1:       .using 1b               # tell assembler no base register
*** /source/bsd-4.3/common/sys/ca/mmu.h	Tue Jul 17 14:53:42 1990
--- mmu.h	Fri Apr  3 09:12:54 1992
***************
*** 21,26 ****
--- 21,27 ----
  #define MMU_TCR  0x15
  #define MMU_RAM  0x16
  #define MMU_ROS  0x17
+ #define	MMU_RMDR 0x18
  #define MMU_TLBS 0x80
  #define	MMU_SEG_TLB 0x81
  #define MMU_CRA  0x83
***************
*** 229,237 ****
  #define MMU_ENDCHAIN(ptr) ((ptr)&0x8000)
  
  #ifdef KERNEL
! extern struct hatipt_entry *MMU_HATIPT;
  extern int MMU_HASHMASK;
! #endif /* KERNEL */
  
  #define MMU_HASH(seg,vpage) ((seg ^ vpage) & MMU_HASHMASK)
  
--- 230,238 ----
  #define MMU_ENDCHAIN(ptr) ((ptr)&0x8000)
  
  #ifdef KERNEL
! extern volatile struct hatipt_entry *MMU_HATIPT;
  extern int MMU_HASHMASK;
! #endif KERNEL
  
  #define MMU_HASH(seg,vpage) ((seg ^ vpage) & MMU_HASHMASK)
  

home help back first fref pref prev next nref lref last post