1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Mt. Xinu. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the University of California, Berkeley. The name of the 14 * University may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * @(#)ka650.c 7.5 (Berkeley) 11/08/88 21 */ 22 23 #if VAX650 24 25 /* 26 * vax650-specific code. 27 */ 28 29 #include "param.h" 30 #include "time.h" 31 #include "kernel.h" 32 #include "systm.h" 33 34 #include "cpu.h" 35 #include "clock.h" 36 #include "psl.h" 37 #include "mem.h" 38 #include "mtpr.h" 39 #include "ka650.h" 40 41 42 ka650_init() 43 { 44 ioaccess(KA650_MERR, KA650MERRmap, sizeof(ka650merr)); 45 ioaccess(KA650_CBD, KA650CBDmap, sizeof(ka650cbd)); 46 ioaccess(KA650_SSC, KA650SSCmap, sizeof(ka650ssc)); 47 ioaccess(KA650_IPCR, KA650IPCRmap, sizeof(ka650ipcr)); 48 ioaccess(KA650_CACHE, KA650CACHEmap, KA650_CACHESIZE); 49 ka650encache(); 50 if (ctob(physmem) > ka650merr.merr_qbmbr) { 51 printf("physmem(0x%x) > qbmbr(0x%x)\n", 52 ctob(physmem), ka650merr.merr_qbmbr); 53 panic("qbus map unprotected"); 54 } 55 } 56 57 ka650_clkstartrt() 58 { 59 mtpr(ICCS, ICCS_IE); 60 } 61 62 ka650_memnop() 63 { 64 /* void */ 65 } 66 67 ka650_memerr() 68 { 69 register char *cp = (char *)0; 70 register int m; 71 extern u_int cache2tag; 72 73 if (ka650cbd.cbd_cacr & CACR_CPE) { 74 printf("cache 2 tag parity error: "); 75 if (time.tv_sec - cache2tag < 7) { 76 ka650discache(); 77 printf("cacheing disabled\n"); 78 } else { 79 cache2tag = time.tv_sec; 80 printf("flushing cache\n"); 81 ka650encache(); 82 } 83 } 84 m = ka650merr.merr_errstat; 85 ka650merr.merr_errstat = MEM_EMASK; 86 if (m & MEM_CDAL) { 87 cp = "Bus Parity"; 88 } else if (m & MEM_RDS) { 89 cp = "Hard ECC"; 90 } else if (m & MEM_CRD) { 91 cp = "Soft ECC"; 92 } 93 if (cp) { 94 printf("%sMemory %s Error: page 0x%x\n", 95 (m & MEM_DMA) ? "DMA " : "", cp, 96 (m & MEM_PAGE) >> MEM_PAGESHFT); 97 } 98 } 99 100 #define NMC650 15 101 char *mc650[] = { 102 0, "FPA proto err", "FPA resv inst", 103 "FPA Ill Stat 2", "FPA Ill Stat 1", "PTE in P0, TB miss", 104 "PTE in P1, TB miss", "PTE in P0, Mod", "PTE in P1, Mod", 105 "Illegal intr IPL", "MOVC state error", "bus read error", 106 "SCB read error", "bus write error", "PCB write error" 107 }; 108 u_int cache1tag; 109 u_int cache1data; 110 u_int cdalerr; 111 u_int cache2tag; 112 113 struct mc650frame { 114 int mc65_bcnt; /* byte count == 0xc */ 115 int mc65_summary; /* summary parameter */ 116 int mc65_mrvaddr; /* most recent vad */ 117 int mc65_istate1; /* internal state */ 118 int mc65_istate2; /* internal state */ 119 int mc65_pc; /* trapped pc */ 120 int mc65_psl; /* trapped psl */ 121 }; 122 123 ka650_mchk(cmcf) 124 caddr_t cmcf; 125 { 126 register struct mc650frame *mcf = (struct mc650frame *)cmcf; 127 register u_int type = mcf->mc65_summary; 128 register u_int i; 129 130 printf("machine check %x", type); 131 if (type >= 0x80 && type <= 0x83) 132 type -= (0x80 + 11); 133 if (type < NMC650 && mc650[type]) 134 printf(": %s", mc650[type]); 135 printf("\n\tvap %x istate1 %x istate2 %x pc %x psl %x\n", 136 mcf->mc65_mrvaddr, mcf->mc65_istate1, mcf->mc65_istate2, 137 mcf->mc65_pc, mcf->mc65_psl); 138 printf("dmaser=0x%b qbear=0x%x dmaear=0x%x\n", 139 ka650merr.merr_dser, DMASER_BITS, ka650merr.merr_qbear, 140 ka650merr.merr_dear); 141 ka650merr.merr_dser = DSER_CLEAR; 142 143 i = mfpr(CAER); 144 mtpr(CAER, CAER_MCC | CAER_DAT | CAER_TAG); 145 if (i & CAER_MCC) { 146 printf("cache 1 "); 147 if (i & CAER_DAT) { 148 printf("data"); 149 i = cache1data; 150 cache1data = time.tv_sec; 151 } 152 if (i & CAER_TAG) { 153 printf("tag"); 154 i = cache1tag; 155 cache1tag = time.tv_sec; 156 } 157 } else if ((i & CAER_MCD) || (ka650merr.merr_errstat & MEM_CDAL)) { 158 printf("CDAL"); 159 i = cdalerr; 160 cdalerr = time.tv_sec; 161 } 162 if (time.tv_sec - i < 7) { 163 ka650discache(); 164 printf(" parity error: cacheing disabled\n"); 165 } else { 166 printf(" parity error: flushing cache\n"); 167 ka650encache(); 168 } 169 /* 170 * May be able to recover if type is 1-4, 0x80 or 0x81, but 171 * only if FPD is set in the saved PSL, or bit VCR in Istate2 172 * is clear. 173 */ 174 if ((type > 0 && type < 5) || type == 11 || type == 12) { 175 if ((mcf->mc65_psl & PSL_FPD) 176 || !(mcf->mc65_istate2 & IS2_VCR)) { 177 ka650_memerr(); 178 return (MCHK_RECOVERED); 179 } 180 } 181 return (MCHK_PANIC); 182 } 183 184 /* 185 * Make sure both caches are off and not in diagnostic mode. Clear the 186 * 2nd level cache (by writing to each quadword entry), then enable it. 187 * Enable 1st level cache too. 188 */ 189 ka650encache() 190 { 191 register int i; 192 193 ka650discache(); 194 for (i = 0; i < (KA650_CACHESIZE / sizeof(ka650cache[0])); i += 2) 195 ka650cache[i] = 0; 196 ka650cbd.cbd_cacr = CACR_CEN; 197 mtpr(CADR, CADR_SEN2 | CADR_SEN1 | CADR_CENI | CADR_CEND); 198 } 199 200 ka650discache() 201 { 202 mtpr(CADR, 0); 203 ka650cbd.cbd_cacr = CACR_CPE; 204 } 205 #endif 206