1 /* $NetBSD: ka750.c,v 1.34 2002/10/02 16:02:35 thorpej 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 CFATTACH_DECL(mem_cmi, sizeof(struct device), 101 ka750_memmatch, ka750_memenable, NULL, NULL); 102 103 int 104 ka750_memmatch(struct device *parent, struct cfdata *cf, void *aux) 105 { 106 struct sbi_attach_args *sa = (struct sbi_attach_args *)aux; 107 108 if (cf->cf_loc[CMICF_TR] != sa->sa_nexnum && 109 cf->cf_loc[CMICF_TR] > CMICF_TR_DEFAULT) 110 return 0; 111 112 if (sa->sa_type != NEX_MEM16) 113 return 0; 114 115 return 1; 116 } 117 118 struct mcr750 { 119 int mc_err; /* error bits */ 120 int mc_inh; /* inhibit crd */ 121 int mc_inf; /* info bits */ 122 }; 123 124 #define M750_ICRD 0x10000000 /* inhibit crd interrupts, in [1] */ 125 #define M750_UNCORR 0xc0000000 /* uncorrectable error, in [0] */ 126 #define M750_CORERR 0x20000000 /* correctable error, in [0] */ 127 128 #define M750_INH(mcr) ((mcr)->mc_inh = 0) 129 #define M750_ENA(mcr) ((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \ 130 (mcr)->mc_inh = M750_ICRD) 131 #define M750_ERR(mcr) ((mcr)->mc_err & (M750_UNCORR|M750_CORERR)) 132 133 #define M750_SYN(err) ((err) & 0x7f) 134 #define M750_ADDR(err) (((err) >> 9) & 0x7fff) 135 136 /* enable crd interrupts */ 137 void 138 ka750_memenable(struct device *parent, struct device *self, void *aux) 139 { 140 struct sbi_attach_args *sa = (struct sbi_attach_args *)aux; 141 struct mcr750 *mcr = (struct mcr750 *)sa->sa_ioh; 142 int k, l, m, cardinfo; 143 144 mcraddr[self->dv_unit] = (caddr_t)sa->sa_ioh; 145 146 /* We will use this info for error reporting - later! */ 147 cardinfo = mcr->mc_inf; 148 switch ((cardinfo >> 24) & 3) { 149 case 0: printf(": L0011 "); 150 break; 151 152 case 1: printf(": L0016 "); 153 m = cardinfo & 0xaaaa; 154 for (k = l = 0; k < 16; k++){ 155 if (m & 1) 156 l++; 157 m >>= 1; 158 } 159 printf("with %d M8750",l); 160 break; 161 162 case 3: printf(": L0022 "); 163 m = cardinfo & 0x5555; 164 for (k = l = 0; k < 16; k++) { 165 if (m & 1) 166 l++; 167 m>>=1; 168 } 169 printf("with %d M7199",l); 170 m = cardinfo & 0xaaaa; 171 if (m) { 172 for (k = l = 0; k < 16; k++) { 173 if (m & 1) 174 l++; 175 m >>= 1; 176 } 177 printf(" and %d M8750",l); 178 } 179 break; 180 } 181 printf("\n"); 182 183 184 M750_ENA((struct mcr750 *)mcraddr[0]); 185 } 186 187 /* log crd errors */ 188 void 189 ka750_memerr() 190 { 191 register struct mcr750 *mcr = (struct mcr750 *)mcraddr[0]; 192 register int err; 193 194 if (M750_ERR(mcr)) { 195 err = mcr->mc_err; /* careful with i/o space refs */ 196 printf("mcr0: %s", err & M750_UNCORR ? 197 "hard error" : "soft ecc"); 198 printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err)); 199 M750_INH(mcr); 200 } 201 } 202 203 char *mc750[]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13", 204 "14","15"}; 205 206 struct mc750frame { 207 int mc5_bcnt; /* byte count == 0x28 */ 208 int mc5_summary; /* summary parameter (as above) */ 209 int mc5_va; /* virtual address register */ 210 int mc5_errpc; /* error pc */ 211 int mc5_mdr; 212 int mc5_svmode; /* saved mode register */ 213 int mc5_rdtimo; /* read lock timeout */ 214 int mc5_tbgpar; /* tb group parity error register */ 215 int mc5_cacherr; /* cache error register */ 216 int mc5_buserr; /* bus error register */ 217 int mc5_mcesr; /* machine check status register */ 218 int mc5_pc; /* trapped pc */ 219 int mc5_psl; /* trapped psl */ 220 }; 221 222 #define MC750_TBERR 2 /* type code of cp tbuf par */ 223 #define MC750_TBPAR 4 /* tbuf par bit in mcesr */ 224 225 int 226 ka750_mchk(caddr_t cmcf) 227 { 228 register struct mc750frame *mcf = (struct mc750frame *)cmcf; 229 register int type = mcf->mc5_summary; 230 int mcsr = mfpr(PR_MCSR); 231 232 printf("machine check %x: %s%s\n", type, mc750[type&0xf], 233 (type&0xf0) ? " abort" : " fault"); 234 printf( 235 "\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n", 236 mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode, 237 mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr); 238 printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n", 239 mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl, 240 mcsr); 241 mtpr(0, PR_TBIA); 242 mtpr(0xf, PR_MCESR); 243 if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) { 244 printf("tbuf par: flushing and returning\n"); 245 return (MCHK_RECOVERED); 246 } 247 return (MCHK_PANIC); 248 } 249 250 void 251 ka750_clrf() 252 { 253 int s = splhigh(); 254 255 #define WAIT while ((mfpr(PR_TXCS) & GC_RDY) == 0) ; 256 257 WAIT; 258 259 mtpr(GC_CWFL|GC_CONS, PR_TXDB); 260 261 WAIT; 262 mtpr(GC_CCFL|GC_CONS, PR_TXDB); 263 264 WAIT; 265 splx(s); 266 } 267