[9242] in Athena Bugs
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) ®s[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) ®s[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)