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