1 /* $NetBSD: ka750.c,v 1.31 2000/06/04 18:02:35 ragge Exp $ */ 2 /* 3 * Copyright (c) 1982, 1986, 1988 The Regents of the University of California. 4 * Copyright (c) 1994 Ludd, University of Lule}, Sweden. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)ka750.c 7.4 (Berkeley) 5/9/91 36 * @(#)autoconf.c 7.20 (Berkeley) 5/9/91 37 */ 38 39 #include <sys/param.h> 40 #include <sys/device.h> 41 #include <sys/systm.h> 42 43 #include <machine/bus.h> 44 #include <machine/ka750.h> 45 #include <machine/mtpr.h> 46 #include <machine/cpu.h> 47 #include <machine/clock.h> 48 #include <machine/sid.h> 49 50 #include <vax/vax/gencons.h> 51 52 #include "locators.h" 53 54 void ctuattach(void); 55 static void ka750_clrf(void); 56 static void ka750_conf(void); 57 static void ka750_memerr(void); 58 static int ka750_mchk(caddr_t); 59 60 61 struct cpu_dep ka750_calls = { 62 0, 63 ka750_mchk, 64 ka750_memerr, 65 ka750_conf, 66 generic_clkread, 67 generic_clkwrite, 68 1, /* ~VUPS */ 69 4, /* SCB pages */ 70 0, /* halt call */ 71 0, /* Reboot call */ 72 ka750_clrf, 73 }; 74 75 static caddr_t mcraddr[4]; /* XXX */ 76 77 void 78 ka750_conf() 79 { 80 printf("cpu0: KA750, hardware rev %d, ucode rev %d, ", 81 V750HARDW(vax_cpudata), V750UCODE(vax_cpudata)); 82 if (mfpr(PR_ACCS) & 255) { 83 printf("FPA present, enabling.\n"); 84 mtpr(0x8000, PR_ACCS); 85 } else 86 printf("no FPA\n"); 87 88 if (mfpr(PR_TODR) == 0) { /* Check for failing battery */ 89 mtpr(1, PR_TODR); 90 printf("WARNING: TODR battery broken\n"); 91 } 92 93 /* Call ctuattach() here so it can setup its vectors. */ 94 ctuattach(); 95 } 96 97 static int ka750_memmatch(struct device *, struct cfdata *, void *); 98 static void ka750_memenable(struct device *, struct device *, void *); 99 100 struct cfattach mem_cmi_ca = { 101 sizeof(struct device), ka750_memmatch, ka750_memenable 102 }; 103 104 int 105 ka750_memmatch(struct device *parent, struct cfdata *cf, void *aux) 106 { 107 struct sbi_attach_args *sa = (struct sbi_attach_args *)aux; 108 109 if (cf->cf_loc[CMICF_TR] != sa->sa_nexnum && 110 cf->cf_loc[CMICF_TR] > CMICF_TR_DEFAULT) 111 return 0; 112 113 if (sa->sa_type != NEX_MEM16) 114 return 0; 115 116 return 1; 117 } 118 119 struct mcr750 { 120 int mc_err; /* error bits */ 121 int mc_inh; /* inhibit crd */ 122 int mc_inf; /* info bits */ 123 }; 124 125 #define M750_ICRD 0x10000000 /* inhibit crd interrupts, in [1] */ 126 #define M750_UNCORR 0xc0000000 /* uncorrectable error, in [0] */ 127 #define M750_CORERR 0x20000000 /* correctable error, in [0] */ 128 129 #define M750_INH(mcr) ((mcr)->mc_inh = 0) 130 #define M750_ENA(mcr) ((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \ 131 (mcr)->mc_inh = M750_ICRD) 132 #define M750_ERR(mcr) ((mcr)->mc_err & (M750_UNCORR|M750_CORERR)) 133 134 #define M750_SYN(err) ((err) & 0x7f) 135 #define M750_ADDR(err) (((err) >> 9) & 0x7fff) 136 137 /* enable crd interrupts */ 138 void 139 ka750_memenable(struct device *parent, struct device *self, void *aux) 140 { 141 struct sbi_attach_args *sa = (struct sbi_attach_args *)aux; 142 struct mcr750 *mcr = (struct mcr750 *)sa->sa_ioh; 143 int k, l, m, cardinfo; 144 145 mcraddr[self->dv_unit] = (caddr_t)sa->sa_ioh; 146 147 /* We will use this info for error reporting - later! */ 148 cardinfo = mcr->mc_inf; 149 switch ((cardinfo >> 24) & 3) { 150 case 0: printf(": L0011 "); 151 break; 152 153 case 1: printf(": L0016 "); 154 m = cardinfo & 0xaaaa; 155 for (k = l = 0; k < 16; k++){ 156 if (m & 1) 157 l++; 158 m >>= 1; 159 } 160 printf("with %d M8750",l); 161 break; 162 163 case 3: printf(": L0022 "); 164 m = cardinfo & 0x5555; 165 for (k = l = 0; k < 16; k++) { 166 if (m & 1) 167 l++; 168 m>>=1; 169 } 170 printf("with %d M7199",l); 171 m = cardinfo & 0xaaaa; 172 if (m) { 173 for (k = l = 0; k < 16; k++) { 174 if (m & 1) 175 l++; 176 m >>= 1; 177 } 178 printf(" and %d M8750",l); 179 } 180 break; 181 } 182 printf("\n"); 183 184 185 M750_ENA((struct mcr750 *)mcraddr[0]); 186 } 187 188 /* log crd errors */ 189 void 190 ka750_memerr() 191 { 192 register struct mcr750 *mcr = (struct mcr750 *)mcraddr[0]; 193 register int err; 194 195 if (M750_ERR(mcr)) { 196 err = mcr->mc_err; /* careful with i/o space refs */ 197 printf("mcr0: %s", err & M750_UNCORR ? 198 "hard error" : "soft ecc"); 199 printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err)); 200 M750_INH(mcr); 201 } 202 } 203 204 char *mc750[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13", 205 "14","15"}; 206 207 struct mc750frame { 208 int mc5_bcnt; /* byte count == 0x28 */ 209 int mc5_summary; /* summary parameter (as above) */ 210 int mc5_va; /* virtual address register */ 211 int mc5_errpc; /* error pc */ 212 int mc5_mdr; 213 int mc5_svmode; /* saved mode register */ 214 int mc5_rdtimo; /* read lock timeout */ 215 int mc5_tbgpar; /* tb group parity error register */ 216 int mc5_cacherr; /* cache error register */ 217 int mc5_buserr; /* bus error register */ 218 int mc5_mcesr; /* machine check status register */ 219 int mc5_pc; /* trapped pc */ 220 int mc5_psl; /* trapped psl */ 221 }; 222 223 #define MC750_TBERR 2 /* type code of cp tbuf par */ 224 #define MC750_TBPAR 4 /* tbuf par bit in mcesr */ 225 226 int 227 ka750_mchk(caddr_t cmcf) 228 { 229 register struct mc750frame *mcf = (struct mc750frame *)cmcf; 230 register int type = mcf->mc5_summary; 231 int mcsr = mfpr(PR_MCSR); 232 233 printf("machine check %x: %s%s\n", type, mc750[type&0xf], 234 (type&0xf0) ? " abort" : " fault"); 235 printf( 236 "\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n", 237 mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode, 238 mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr); 239 printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n", 240 mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl, 241 mcsr); 242 mtpr(0, PR_TBIA); 243 mtpr(0xf, PR_MCESR); 244 if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) { 245 printf("tbuf par: flushing and returning\n"); 246 return (MCHK_RECOVERED); 247 } 248 return (MCHK_PANIC); 249 } 250 251 void 252 ka750_clrf() 253 { 254 int s = splhigh(); 255 256 #define WAIT while ((mfpr(PR_TXCS) & GC_RDY) == 0) ; 257 258 WAIT; 259 260 mtpr(GC_CWFL|GC_CONS, PR_TXDB); 261 262 WAIT; 263 mtpr(GC_CCFL|GC_CONS, PR_TXDB); 264 265 WAIT; 266 splx(s); 267 } 268