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