1 /* 2 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)ka780.c 7.3 (Berkeley) 12/16/90 7 */ 8 9 #if VAX780 10 11 /* 12 * 780-specific code. 13 */ 14 15 #include "sys/param.h" 16 17 #include "../include/cpu.h" 18 #include "mem.h" 19 #include "../include/mtpr.h" 20 21 /* 22 * Memory controller register usage varies per controller. 23 */ 24 struct mcr780 { 25 int mc_reg[4]; 26 }; 27 28 #define M780_ICRD 0x40000000 /* inhibit crd interrupts, in [2] */ 29 #define M780_HIER 0x20000000 /* high error rate, in reg[2] */ 30 #define M780_ERLOG 0x10000000 /* error log request, in reg[2] */ 31 /* on a 780, memory crd's occur only when bit 15 is set in the SBIER */ 32 /* register; bit 14 there is an error bit which we also clear */ 33 /* these bits are in the back of the ``red book'' (or in the VMS code) */ 34 35 #define M780C_INH(mcr) \ 36 (((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) 37 #define M780C_ENA(mcr) \ 38 (((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) 39 #define M780C_ERR(mcr) \ 40 ((mcr)->mc_reg[2] & (M780_ERLOG)) 41 42 #define M780C_SYN(mcr) ((mcr)->mc_reg[2] & 0xff) 43 #define M780C_ADDR(mcr) (((mcr)->mc_reg[2] >> 8) & 0xfffff) 44 45 #define M780EL_INH(mcr) \ 46 (((mcr)->mc_reg[2] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) 47 #define M780EL_ENA(mcr) \ 48 (((mcr)->mc_reg[2] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) 49 #define M780EL_ERR(mcr) \ 50 ((mcr)->mc_reg[2] & (M780_ERLOG)) 51 52 #define M780EL_SYN(mcr) ((mcr)->mc_reg[2] & 0x7f) 53 #define M780EL_ADDR(mcr) (((mcr)->mc_reg[2] >> 11) & 0x1ffff) 54 55 #define M780EU_INH(mcr) \ 56 (((mcr)->mc_reg[3] = (M780_ICRD|M780_HIER|M780_ERLOG)), mtpr(SBIER, 0)) 57 #define M780EU_ENA(mcr) \ 58 (((mcr)->mc_reg[3] = (M780_HIER|M780_ERLOG)), mtpr(SBIER, 3<<14)) 59 #define M780EU_ERR(mcr) \ 60 ((mcr)->mc_reg[3] & (M780_ERLOG)) 61 62 #define M780EU_SYN(mcr) ((mcr)->mc_reg[3] & 0x7f) 63 #define M780EU_ADDR(mcr) (((mcr)->mc_reg[3] >> 11) & 0x1ffff) 64 65 /* enable crd interrrupts */ 66 ka780_memenable() 67 { 68 register struct mcr780 *mcr; 69 register int m; 70 71 for (m = 0; m < nmcr; m++) { 72 mcr = (struct mcr780 *)mcraddr[m]; 73 switch (mcrtype[m]) { 74 75 case M780C: 76 M780C_ENA(mcr); 77 break; 78 79 case M780EL: 80 M780EL_ENA(mcr); 81 break; 82 83 case M780EU: 84 M780EU_ENA(mcr); 85 break; 86 } 87 } 88 } 89 90 /* log crd errors */ 91 ka780_memerr() 92 { 93 register struct mcr780 *mcr; 94 register int m; 95 96 for (m = 0; m < nmcr; m++) { 97 mcr = (struct mcr780 *)mcraddr[m]; 98 switch (mcrtype[m]) { 99 100 case M780C: 101 if (M780C_ERR(mcr)) { 102 printf("mcr%d: soft ecc addr %x syn %x\n", 103 m, M780C_ADDR(mcr), M780C_SYN(mcr)); 104 #ifdef TRENDATA 105 memlog(m, mcr); 106 #endif 107 M780C_INH(mcr); 108 } 109 break; 110 111 case M780EL: 112 if (M780EL_ERR(mcr)) { 113 printf("mcr%d: soft ecc addr %x syn %x\n", 114 m, M780EL_ADDR(mcr), M780EL_SYN(mcr)); 115 M780EL_INH(mcr); 116 } 117 break; 118 119 case M780EU: 120 if (M780EU_ERR(mcr)) { 121 printf("mcr%d: soft ecc addr %x syn %x\n", 122 m, M780EU_ADDR(mcr), M780EU_SYN(mcr)); 123 M780EU_INH(mcr); 124 } 125 break; 126 } 127 } 128 } 129 130 #ifdef TRENDATA 131 /* 132 * Figure out what chip to replace on Trendata boards. 133 * Assumes all your memory is Trendata or the non-Trendata 134 * memory never fails.. 135 */ 136 struct { 137 u_char m_syndrome; 138 char m_chip[4]; 139 } memlogtab[] = { 140 0x01, "C00", 0x02, "C01", 0x04, "C02", 0x08, "C03", 141 0x10, "C04", 0x19, "L01", 0x1A, "L02", 0x1C, "L04", 142 0x1F, "L07", 0x20, "C05", 0x38, "L00", 0x3B, "L03", 143 0x3D, "L05", 0x3E, "L06", 0x40, "C06", 0x49, "L09", 144 0x4A, "L10", 0x4c, "L12", 0x4F, "L15", 0x51, "L17", 145 0x52, "L18", 0x54, "L20", 0x57, "L23", 0x58, "L24", 146 0x5B, "L27", 0x5D, "L29", 0x5E, "L30", 0x68, "L08", 147 0x6B, "L11", 0x6D, "L13", 0x6E, "L14", 0x70, "L16", 148 0x73, "L19", 0x75, "L21", 0x76, "L22", 0x79, "L25", 149 0x7A, "L26", 0x7C, "L28", 0x7F, "L31", 0x80, "C07", 150 0x89, "U01", 0x8A, "U02", 0x8C, "U04", 0x8F, "U07", 151 0x91, "U09", 0x92, "U10", 0x94, "U12", 0x97, "U15", 152 0x98, "U16", 0x9B, "U19", 0x9D, "U21", 0x9E, "U22", 153 0xA8, "U00", 0xAB, "U03", 0xAD, "U05", 0xAE, "U06", 154 0xB0, "U08", 0xB3, "U11", 0xB5, "U13", 0xB6, "U14", 155 0xB9, "U17", 0xBA, "U18", 0xBC, "U20", 0xBF, "U23", 156 0xC1, "U25", 0xC2, "U26", 0xC4, "U28", 0xC7, "U31", 157 0xE0, "U24", 0xE3, "U27", 0xE5, "U29", 0xE6, "U30" 158 }; 159 160 memlog(m, mcr) 161 int m; 162 struct mcr780 *mcr; 163 { 164 register i; 165 166 for (i = 0; i < (sizeof (memlogtab) / sizeof (memlogtab[0])); i++) 167 if ((u_char)(M780C_SYN(mcr)) == memlogtab[i].m_syndrome) { 168 printf ( 169 "mcr%d: replace %s chip in %s bank of memory board %d (0-15)\n", 170 m, 171 memlogtab[i].m_chip, 172 (M780C_ADDR(mcr) & 0x8000) ? "upper" : "lower", 173 (M780C_ADDR(mcr) >> 16)); 174 return; 175 } 176 printf ("mcr%d: multiple errors, not traceable\n", m); 177 break; 178 } 179 #endif TRENDATA 180 181 extern char *mc780750[]; 182 183 struct mc780frame { 184 int mc8_bcnt; /* byte count == 0x28 */ 185 int mc8_summary; /* summary parameter (as above) */ 186 int mc8_cpues; /* cpu error status */ 187 int mc8_upc; /* micro pc */ 188 int mc8_vaviba; /* va/viba register */ 189 int mc8_dreg; /* d register */ 190 int mc8_tber0; /* tbuf error reg 0 */ 191 int mc8_tber1; /* tbuf error reg 1 */ 192 int mc8_timo; /* timeout address divided by 4 */ 193 int mc8_parity; /* parity */ 194 int mc8_sbier; /* sbi error register */ 195 int mc8_pc; /* trapped pc */ 196 int mc8_psl; /* trapped psl */ 197 }; 198 199 ka780_mchk(cmcf) 200 caddr_t cmcf; 201 { 202 register struct mc780frame *mcf = (struct mc780frame *)cmcf; 203 register int type = mcf->mc8_summary; 204 register int sbifs; 205 206 printf("machine check %x: %s%s\n", type, mc780750[type&0xf], 207 (type&0xf0) ? " abort" : " fault"); 208 printf("\tcpues %x upc %x va/viba %x dreg %x tber %x %x\n", 209 mcf->mc8_cpues, mcf->mc8_upc, mcf->mc8_vaviba, 210 mcf->mc8_dreg, mcf->mc8_tber0, mcf->mc8_tber1); 211 sbifs = mfpr(SBIFS); 212 printf("\ttimo %x parity %x sbier %x pc %x psl %x sbifs %x\n", 213 mcf->mc8_timo*4, mcf->mc8_parity, mcf->mc8_sbier, 214 mcf->mc8_pc, mcf->mc8_psl, sbifs); 215 /* THE FUNNY BITS IN THE FOLLOWING ARE FROM THE ``BLACK BOOK'' */ 216 /* AND SHOULD BE PUT IN AN ``sbi.h'' */ 217 mtpr(SBIFS, sbifs &~ 0x2000000); 218 mtpr(SBIER, mfpr(SBIER) | 0x70c0); 219 return (MCHK_PANIC); 220 } 221 #endif 222