1 /* $NetBSD: ka860.c,v 1.16 2000/08/09 03:02:54 tv Exp $ */ 2 /* 3 * Copyright (c) 1986, 1988 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. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)ka860.c 7.4 (Berkeley) 12/16/90 35 */ 36 37 /* 38 * VAX 8600 specific routines. 39 * Also contains abus spec's and memory init routines. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/device.h> 44 #include <sys/systm.h> 45 46 #include <machine/cpu.h> 47 #include <machine/clock.h> 48 #include <machine/mtpr.h> 49 #include <machine/nexus.h> 50 #include <machine/ioa.h> 51 #include <machine/sid.h> 52 53 #include <vax/vax/gencons.h> 54 55 static void ka86_memerr __P((void)); 56 static int ka86_mchk __P((caddr_t)); 57 static void ka86_reboot __P((int)); 58 static void ka86_clrf __P((void)); 59 static void ka860_init __P((struct device *)); 60 61 void crlattach __P((void)); 62 63 struct cpu_dep ka860_calls = { 64 0, 65 ka86_mchk, 66 ka86_memerr, 67 0, 68 generic_clkread, 69 generic_clkwrite, 70 6, /* ~VUPS */ 71 10, /* SCB pages */ 72 0, /* Halt call, nothing special */ 73 ka86_reboot, 74 ka86_clrf, 75 }; 76 77 /* 78 * 8600 memory register (MERG) bit definitions 79 */ 80 #define M8600_ICRD 0x400 /* inhibit crd interrupts */ 81 #define M8600_TB_ERR 0xf00 /* translation buffer error mask */ 82 83 /* 84 * MDECC register 85 */ 86 #define M8600_ADDR_PE 0x080000 /* address parity error */ 87 #define M8600_DBL_ERR 0x100000 /* data double bit error */ 88 #define M8600_SNG_ERR 0x200000 /* data single bit error */ 89 #define M8600_BDT_ERR 0x400000 /* bad data error */ 90 91 /* 92 * ESPA register is used to address scratch pad registers in the Ebox. 93 * To access a register in the scratch pad, write the ESPA with the address 94 * and then read the ESPD register. 95 * 96 * NOTE: In assmebly code, the mfpr instruction that reads the ESPD 97 * register must immedately follow the mtpr instruction that setup 98 * the ESPA register -- per the VENUS processor register spec. 99 * 100 * The scratchpad registers that are supplied for a single bit ECC 101 * error are: 102 */ 103 #define SPAD_MSTAT1 0x25 /* scratch pad mstat1 register */ 104 #define SPAD_MSTAT2 0x26 /* scratch pad mstat2 register */ 105 #define SPAD_MDECC 0x27 /* scratch pad mdecc register */ 106 #define SPAD_MEAR 0x2a /* scratch pad mear register */ 107 108 #define M8600_MEMERR(mdecc) ((mdecc) & 0x780000) 109 #define M8600_HRDERR(mdecc) ((mdecc) & 0x580000) 110 #define M8600_SYN(mdecc) (((mdecc) >> 9) & 0x3f) 111 #define M8600_ADDR(mear) ((mear) & 0x3ffffffc) 112 #define M8600_ARRAY(mear) (((mear) >> 22) & 0x0f) 113 114 #define M8600_MDECC_BITS \ 115 "\20\27BAD_DT_ERR\26SNG_BIT_ERR\25DBL_BIT_ERR\24ADDR_PE" 116 117 #define M8600_MSTAT1_BITS "\20\30CPR_PE_A\27CPR_PE_B\26ABUS_DT_PE\ 118 \25ABUS_CTL_MSK_PE\24ABUS_ADR_PE\23ABUS_C/A_CYCLE\22ABUS_ADP_1\21ABUS_ADP_0\ 119 \20TB_MISS\17BLK_HIT\16C0_TAG_MISS\15CHE_MISS\14TB_VAL_ERR\13TB_PTE_B_PE\ 120 \12TB_PTE_A_PE\11TB_TAG_PE\10WR_DT_PE_B3\7WR_DT_PE_B2\6WR_DT_PE_B1\ 121 \5WR_DT_PE_B0\4CHE_RD_DT_PE\3CHE_SEL\2ANY_REFL\1CP_BW_CHE_DT_PE" 122 123 #define M8600_MSTAT2_BITS "\20\20CP_BYT_WR\17ABUS_BD_DT_CODE\10MULT_ERR\ 124 \7CHE_TAG_PE\6CHE_TAG_W_PE\5CHE_WRTN_BIT\4NXM\3CP-IO_BUF_ERR\2MBOX_LOCK" 125 126 /* log CRD errors */ 127 void 128 ka86_memerr() 129 { 130 register int reg11 = 0; /* known to be r11 below */ 131 int mdecc, mear, mstat1, mstat2, array; 132 133 /* 134 * Scratchpad registers in the Ebox must be read by 135 * storing their ID number in ESPA and then immediately 136 * reading ESPD's contents with no other intervening 137 * machine instructions! 138 * 139 * The asm's below have a number of constants which 140 * are defined correctly above and in mtpr.h. 141 */ 142 #ifdef lint 143 reg11 = 0; 144 #else 145 asm("mtpr $0x27,$0x4e; mfpr $0x4f,%0":: "r" (reg11)); 146 #endif 147 mdecc = reg11; /* must acknowledge interrupt? */ 148 if (M8600_MEMERR(mdecc)) { 149 asm("mtpr $0x2a,$0x4e; mfpr $0x4f,%0":: "r" (reg11)); 150 mear = reg11; 151 asm("mtpr $0x25,$0x4e; mfpr $0x4f,%0":: "r" (reg11)); 152 mstat1 = reg11; 153 asm("mtpr $0x26,$0x4e; mfpr $0x4f,%0":: "r" (reg11)); 154 mstat2 = reg11; 155 array = M8600_ARRAY(mear); 156 157 { 158 char sbuf[256], sbuf2[256]; 159 160 printf("mcr0: ecc error, addr %x (array %d) syn %x\n", 161 M8600_ADDR(mear), array, M8600_SYN(mdecc)); 162 163 bitmask_snprintf(mstat1, M8600_MSTAT1_BITS, sbuf, sizeof(sbuf)); 164 bitmask_snprintf(mstat2, M8600_MSTAT2_BITS, sbuf2, sizeof(sbuf2)); 165 printf("\tMSTAT1 = %s\n\tMSTAT2 = %s\n", sbuf, sbuf2); 166 } 167 168 mtpr(0, PR_EHSR); 169 mtpr(mfpr(PR_MERG) | M8600_ICRD, PR_MERG); 170 } 171 } 172 173 #define NMC8600 7 174 char *mc8600[] = { 175 "unkn type", "fbox error", "ebox error", "ibox error", 176 "mbox error", "tbuf error", "mbox 1D error" 177 }; 178 /* codes for above */ 179 #define MC_FBOX 1 180 #define MC_EBOX 2 181 #define MC_IBOX 3 182 #define MC_MBOX 4 183 #define MC_TBUF 5 184 #define MC_MBOX1D 6 185 186 /* error bits */ 187 #define MBOX_FE 0x8000 /* Mbox fatal error */ 188 #define FBOX_SERV 0x10000000 /* Fbox service error */ 189 #define IBOX_ERR 0x2000 /* Ibox error */ 190 #define EBOX_ERR 0x1e00 /* Ebox error */ 191 #define MBOX_1D 0x81d0000 /* Mbox 1D error */ 192 #define EDP_PE 0x200 193 194 struct mc8600frame { 195 int mc86_bcnt; /* byte count == 0x58 */ 196 int mc86_ehmsts; 197 int mc86_evmqsav; 198 int mc86_ebcs; 199 int mc86_edpsr; 200 int mc86_cslint; 201 int mc86_ibesr; 202 int mc86_ebxwd1; 203 int mc86_ebxwd2; 204 int mc86_ivasav; 205 int mc86_vibasav; 206 int mc86_esasav; 207 int mc86_isasav; 208 int mc86_cpc; 209 int mc86_mstat1; 210 int mc86_mstat2; 211 int mc86_mdecc; 212 int mc86_merg; 213 int mc86_cshctl; 214 int mc86_mear; 215 int mc86_medr; 216 int mc86_accs; 217 int mc86_cses; 218 int mc86_pc; /* trapped pc */ 219 int mc86_psl; /* trapped psl */ 220 }; 221 222 /* machine check */ 223 int 224 ka86_mchk(cmcf) 225 caddr_t cmcf; 226 { 227 register struct mc8600frame *mcf = (struct mc8600frame *)cmcf; 228 register int type; 229 230 if (mcf->mc86_ebcs & MBOX_FE) 231 mcf->mc86_ehmsts |= MC_MBOX; 232 else if (mcf->mc86_ehmsts & FBOX_SERV) 233 mcf->mc86_ehmsts |= MC_FBOX; 234 else if (mcf->mc86_ebcs & EBOX_ERR) { 235 if (mcf->mc86_ebcs & EDP_PE) 236 mcf->mc86_ehmsts |= MC_MBOX; 237 else 238 mcf->mc86_ehmsts |= MC_EBOX; 239 } else if (mcf->mc86_ehmsts & IBOX_ERR) 240 mcf->mc86_ehmsts |= MC_IBOX; 241 else if (mcf->mc86_mstat1 & M8600_TB_ERR) 242 mcf->mc86_ehmsts |= MC_TBUF; 243 else if ((mcf->mc86_cslint & MBOX_1D) == MBOX_1D) 244 mcf->mc86_ehmsts |= MC_MBOX1D; 245 246 type = mcf->mc86_ehmsts & 0x7; 247 printf("machine check %x: %s\n", type, 248 type < NMC8600 ? mc8600[type] : "???"); 249 printf("\tehm.sts %x evmqsav %x ebcs %x edpsr %x cslint %x\n", 250 mcf->mc86_ehmsts, mcf->mc86_evmqsav, mcf->mc86_ebcs, 251 mcf->mc86_edpsr, mcf->mc86_cslint); 252 printf("\tibesr %x ebxwd %x %x ivasav %x vibasav %x\n", 253 mcf->mc86_ibesr, mcf->mc86_ebxwd1, mcf->mc86_ebxwd2, 254 mcf->mc86_ivasav, mcf->mc86_vibasav); 255 printf("\tesasav %x isasav %x cpc %x mstat %x %x mdecc %x\n", 256 mcf->mc86_esasav, mcf->mc86_isasav, mcf->mc86_cpc, 257 mcf->mc86_mstat1, mcf->mc86_mstat2, mcf->mc86_mdecc); 258 printf("\tmerg %x cshctl %x mear %x medr %x accs %x cses %x\n", 259 mcf->mc86_merg, mcf->mc86_cshctl, mcf->mc86_mear, 260 mcf->mc86_medr, mcf->mc86_accs, mcf->mc86_cses); 261 printf("\tpc %x psl %x\n", mcf->mc86_pc, mcf->mc86_psl); 262 mtpr(0, PR_EHSR); 263 return (MCHK_PANIC); 264 } 265 266 struct ka86 { 267 unsigned snr:12, 268 plant:4, 269 eco:7, 270 v8650:1, 271 type:8; 272 }; 273 274 void 275 ka860_init(self) 276 struct device *self; 277 { 278 struct ka86 *ka86 = (void *)&vax_cpudata; 279 280 /* Enable cache */ 281 mtpr(3, PR_CSWP); 282 283 printf(": CPU serial number %d(%d), hardware ECO level %d(%d)\n%s: ", 284 ka86->snr, ka86->plant, ka86->eco >> 4, ka86->eco, self->dv_xname); 285 if (mfpr(PR_ACCS) & 255) { 286 printf("FPA present, type %d, serial number %d, enabling.\n", 287 mfpr(PR_ACCS) & 255, mfpr(PR_ACCS) >> 16); 288 mtpr(0x8000, PR_ACCS); 289 } else 290 printf("no FPA\n"); 291 /* enable CRD reports */ 292 mtpr(mfpr(PR_MERG) & ~M8600_ICRD, PR_MERG); 293 crlattach(); 294 } 295 296 /* 297 * Clear restart flag. 298 */ 299 void 300 ka86_clrf() 301 { 302 /* 303 * We block all interrupts here so that there won't be any 304 * interrupts for an ongoing printout. 305 */ 306 int s = splhigh(), old = mfpr(PR_TXCS); 307 308 #define WAIT while ((mfpr(PR_TXCS) & GC_RDY) == 0) ; 309 310 WAIT; 311 312 /* Enable channel to console */ 313 mtpr(GC_LT|GC_WRT, PR_TXCS); 314 WAIT; 315 316 /* clear warm start flag */ 317 mtpr(GC_CWFL, PR_TXDB); 318 WAIT; 319 320 /* clear cold start flag */ 321 mtpr(GC_CCFL, PR_TXDB); 322 WAIT; 323 324 /* restore old state */ 325 mtpr(old|GC_WRT, PR_TXCS); 326 splx(s); 327 } 328 329 void 330 ka86_reboot(howto) 331 int howto; 332 { 333 WAIT; 334 335 /* Enable channel to console */ 336 mtpr(GC_LT|GC_WRT, PR_TXCS); 337 WAIT; 338 339 mtpr(GC_BTFL, PR_TXDB); 340 WAIT; 341 342 asm("halt"); 343 } 344 345 static int abus_print __P((void *, const char *)); 346 static int abus_match __P((struct device *, struct cfdata *, void *)); 347 static void abus_attach __P((struct device *, struct device *, void*)); 348 349 struct cfattach abus_ca = { 350 sizeof(struct device), abus_match, abus_attach 351 }; 352 353 /* 354 * Abus is the master bus on VAX 8600. 355 */ 356 int 357 abus_match(parent, cf, aux) 358 struct device *parent; 359 struct cfdata *cf; 360 void *aux; 361 { 362 if (vax_bustype == VAX_ABUS) 363 return 1; 364 return 0; 365 } 366 367 void 368 abus_attach(parent, self, aux) 369 struct device *parent, *self; 370 void *aux; 371 { 372 volatile int tmp; 373 volatile struct sbia_regs *sbiar; 374 struct ioa *ioa; 375 int type, i; 376 struct bp_conf bp; 377 378 /* 379 * Init CPU. 380 */ 381 ka860_init(self); 382 383 for (i = 0; i < MAXNIOA; i++) { 384 ioa = (struct ioa *)vax_map_physmem((paddr_t)IOA8600(0), 385 (IOAMAPSIZ / VAX_NBPG)); 386 if (badaddr((caddr_t)ioa, 4)) { 387 vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG)); 388 continue; 389 } 390 tmp = ioa->ioacsr.ioa_csr; 391 type = tmp & IOA_TYPMSK; 392 393 switch (type) { 394 395 case IOA_SBIA: 396 bp.type = "sbi"; 397 bp.num = i; 398 config_found(self, &bp, abus_print); 399 sbiar = (void *)ioa; 400 sbiar->sbi_errsum = -1; 401 sbiar->sbi_error = 0x1000; 402 sbiar->sbi_fltsts = 0xc0000; 403 break; 404 405 default: 406 printf("IOAdapter %x unsupported\n", type); 407 break; 408 } 409 vax_unmap_physmem((vaddr_t)ioa, (IOAMAPSIZ / VAX_NBPG)); 410 } 411 } 412 413 int 414 abus_print(aux, hej) 415 void *aux; 416 const char *hej; 417 { 418 struct bp_conf *bp = aux; 419 if (hej) 420 printf("%s at %s", bp->type, hej); 421 return (UNCONF); 422 } 423