|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Chris Torek. ! 7: * ! 8: * Redistribution is only permitted until one year after the first shipment ! 9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 10: * binary forms are permitted provided that: (1) source distributions retain ! 11: * this entire copyright notice and comment, and (2) distributions including ! 12: * binaries display the following acknowledgement: This product includes ! 13: * software developed by the University of California, Berkeley and its ! 14: * contributors'' in the documentation or other materials provided with the ! 15: * distribution and in all advertising materials mentioning features or use ! 16: * of this software. Neither the name of the University nor the names of ! 17: * its contributors may be used to endorse or promote products derived from ! 18: * this software without specific prior written permission. ! 19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 22: * ! 23: * @(#)ka820.c 7.3 (Berkeley) 6/28/90 ! 24: */ ! 25: ! 26: #if VAX8200 ! 27: ! 28: /* ! 29: * KA820 specific CPU code. (Note that the VAX8200 uses a KA820, not ! 30: * a KA8200. Sigh.) ! 31: */ ! 32: ! 33: #include "param.h" ! 34: #include "time.h" ! 35: #include "kernel.h" ! 36: #include "vmmac.h" ! 37: ! 38: #include "cpu.h" ! 39: #include "clock.h" ! 40: #include "ka820.h" ! 41: #include "mem.h" ! 42: #include "mtpr.h" ! 43: #include "pte.h" ! 44: ! 45: #include "../vaxbi/bireg.h" ! 46: ! 47: extern struct pte Clockmap[]; ! 48: extern struct pte RX50map[]; ! 49: extern struct pte Ka820map[]; ! 50: struct ka820clock ka820clock; ! 51: struct ka820port ka820port; ! 52: ! 53: #ifdef notyet ! 54: extern struct pte BRAMmap[]; ! 55: extern struct pte EEPROMmap[]; ! 56: char bootram[KA820_BRPAGES * NBPG]; ! 57: char eeprom[KA820_EEPAGES * NBPG]; ! 58: #endif ! 59: ! 60: ka820_init() ! 61: { ! 62: register int csr; ! 63: ! 64: /* map in the various devices */ ! 65: *(int *)&Ka820map[0] = PG_V|PG_KW|btop(KA820_PORTADDR); ! 66: *(int *)&RX50map[0] = PG_V|PG_KW|btop(KA820_RX50ADDR); ! 67: *(int *)&Clockmap[0] = PG_V|PG_KW|btop(KA820_CLOCKADDR); ! 68: #ifdef notyet ! 69: ioaccess(bootram, BRAMmap, KA820_BRPAGES * NBPG); ! 70: ioaccess(eeprom, EEPROMmap, KA820_EEPAGES * NBPG); ! 71: #else ! 72: mtpr(TBIA, 0); ! 73: #endif ! 74: ! 75: /* reset the console and enable the RX50 */ ! 76: csr = ka820port.csr; ! 77: csr &= ~KA820PORT_RSTHALT; /* ??? */ ! 78: csr |= KA820PORT_CONSCLR | KA820PORT_CRDCLR | KA820PORT_CONSEN | ! 79: KA820PORT_RXIE; ! 80: ka820port.csr = csr; ! 81: } ! 82: ! 83: /* Set system time from clock */ ! 84: /* ARGSUSED */ ! 85: ka820_clkread(base) ! 86: time_t base; ! 87: { ! 88: register struct ka820clock *clock = &ka820clock; ! 89: struct chiptime c; ! 90: int s, rv; ! 91: ! 92: rv = CLKREAD_OK; ! 93: /* I wish I knew the differences between these */ ! 94: if ((clock->csr3 & KA820CLK_3_VALID) == 0) { ! 95: printf("WARNING: TOY clock not marked valid\n"); ! 96: rv = CLKREAD_WARN; ! 97: } ! 98: if ((clock->csr1 & KA820CLK_1_GO) != KA820CLK_1_GO) { ! 99: printf("WARNING: TOY clock stopped\n"); ! 100: rv = CLKREAD_WARN; ! 101: } ! 102: /* THIS IS NOT RIGHT (clock may change on us) */ ! 103: s = splhigh(); ! 104: while (clock->csr0 & KA820CLK_0_BUSY) ! 105: /* void */; ! 106: c.sec = clock->sec; ! 107: c.min = clock->min; ! 108: c.hour = clock->hr; ! 109: c.day = clock->day; ! 110: c.mon = clock->mon; ! 111: c.year = clock->yr; ! 112: splx(s); ! 113: ! 114: /* the darn thing needs tweaking! */ ! 115: c.sec >>= 1; /* tweak */ ! 116: c.min >>= 1; /* tweak */ ! 117: c.hour >>= 1; /* tweak */ ! 118: c.day >>= 1; /* tweak */ ! 119: c.mon >>= 1; /* tweak */ ! 120: c.year >>= 1; /* tweak */ ! 121: ! 122: time.tv_sec = chiptotime(&c); ! 123: return (time.tv_sec ? rv : CLKREAD_BAD); ! 124: } ! 125: ! 126: /* store time into clock */ ! 127: ka820_clkwrite() ! 128: { ! 129: register struct ka820clock *clock = &ka820clock; ! 130: struct chiptime c; ! 131: int s; ! 132: ! 133: timetochip(&c); ! 134: ! 135: /* play it again, sam (or mike or kirk or ...) */ ! 136: c.sec <<= 1; /* tweak */ ! 137: c.min <<= 1; /* tweak */ ! 138: c.hour <<= 1; /* tweak */ ! 139: c.day <<= 1; /* tweak */ ! 140: c.mon <<= 1; /* tweak */ ! 141: c.year <<= 1; /* tweak */ ! 142: ! 143: s = splhigh(); ! 144: clock->csr1 = KA820CLK_1_SET; ! 145: while (clock->csr0 & KA820CLK_0_BUSY) ! 146: /* void */; ! 147: clock->sec = c.sec; ! 148: clock->min = c.min; ! 149: clock->hr = c.hour; ! 150: clock->day = c.day; ! 151: clock->mon = c.mon; ! 152: clock->yr = c.year; ! 153: /* should we set a `rate'? */ ! 154: clock->csr1 = KA820CLK_1_GO; ! 155: splx(s); ! 156: } ! 157: ! 158: /* ! 159: * MS820 support. ! 160: */ ! 161: struct ms820regs { ! 162: struct biiregs biic; /* BI interface chip */ ! 163: u_long ms_gpr[4]; /* the four gprs (unused) */ ! 164: int ms_csr1; /* control/status register 1 */ ! 165: int ms_csr2; /* control/status register 2 */ ! 166: }; ! 167: ! 168: /* ! 169: * Bits in CSR1. ! 170: */ ! 171: #define MS1_ERRSUM 0x80000000 /* error summary (ro) */ ! 172: #define MS1_ECCDIAG 0x40000000 /* ecc diagnostic (rw) */ ! 173: #define MS1_ECCDISABLE 0x20000000 /* ecc disable (rw) */ ! 174: #define MS1_MSIZEMASK 0x1ffc0000 /* mask for memory size (ro) */ ! 175: #define MS1_RAMTYMASK 0x00030000 /* mask for ram type (ro) */ ! 176: #define MS1_RAMTY64K 0x00000000 /* 64K chips */ ! 177: #define MS1_RAMTY256K 0x00010000 /* 256K chips */ ! 178: /* types 2 and 3 reserved */ ! 179: #define MS1_CRDINH 0x00008000 /* inhibit crd interrupts (rw) */ ! 180: #define MS1_MEMVALID 0x00004000 /* memory has been written (ro) */ ! 181: #define MS1_INTLK 0x00002000 /* interlock flag (ro) */ ! 182: #define MS1_BROKE 0x00001000 /* broken (rw) */ ! 183: #define MS1_MBZ 0x00000880 /* zero */ ! 184: #define MS1_MWRITEERR 0x00000400 /* rds during masked write (rw) */ ! 185: #define MS1_CNTLERR 0x00000200 /* internal timing busted (rw) */ ! 186: #define MS1_INTLV 0x00000100 /* internally interleaved (ro) */ ! 187: #define MS1_DIAGC 0x0000007f /* ecc diagnostic bits (rw) */ ! 188: ! 189: /* ! 190: * Bits in CSR2. ! 191: */ ! 192: #define MS2_RDSERR 0x80000000 /* rds error (rw) */ ! 193: #define MS2_HIERR 0x40000000 /* high error rate (rw) */ ! 194: #define MS2_CRDERR 0x20000000 /* crd error (rw) */ ! 195: #define MS2_ADRSERR 0x10000000 /* rds due to addr par err (rw) */ ! 196: #define MS2_MBZ 0x0f000080 /* zero */ ! 197: #define MS2_ADDR 0x00fffe00 /* address in error (relative) (ro) */ ! 198: #define MS2_INTLVADDR 0x00000100 /* error was in bank 1 (ro) */ ! 199: #define MS2_SYN 0x0000007f /* error syndrome (ro, rw diag) */ ! 200: ! 201: ! 202: ka820_memenable() ! 203: { ! 204: register struct ms820regs *mcr; ! 205: register int m; ! 206: ! 207: for (m = 0; m < nmcr; m++) { ! 208: mcr = (struct ms820regs *)mcraddr[m]; ! 209: /* ! 210: * This will be noisy. Should we do anything ! 211: * about that? ! 212: */ ! 213: if ((mcr->biic.bi_csr & BICSR_STS) == 0) ! 214: printf("mcr%d: failed self test\n", m); ! 215: else { ! 216: mcr->ms_csr1 = MS1_MWRITEERR | MS1_CNTLERR; ! 217: mcr->ms_csr2 = MS2_RDSERR | MS2_HIERR | ! 218: MS2_CRDERR | MS2_ADRSERR; ! 219: } ! 220: } ! 221: } ! 222: ! 223: ka820_memerr() ! 224: { ! 225: register struct ms820regs *mcr; ! 226: register int m, hard; ! 227: register char *type; ! 228: static char b1[] = "\20\40ERRSUM\37ECCDIAG\36ECCDISABLE\20CRDINH\17VALID\ ! 229: \16INTLK\15BROKE\13MWRITEERR\12CNTLERR\11INTLV"; ! 230: static char b2[] = "\20\40RDS\37HIERR\36CRD\35ADRS"; ! 231: ! 232: for (m = 0; m < nmcr; m++) { ! 233: mcr = (struct ms820regs *)mcraddr[m]; ! 234: printf("mcr%d: csr1=%b csr2=%b\n", m, mcr->ms_csr1, b1, mcr->ms_csr2, b2); ! 235: if ((mcr->ms_csr1 & MS1_ERRSUM) == 0) ! 236: continue; ! 237: hard = 1; ! 238: if (mcr->ms_csr1 & MS1_BROKE) ! 239: type = "broke"; ! 240: else if (mcr->ms_csr1 & MS1_CNTLERR) ! 241: type = "cntl err"; ! 242: else if (mcr->ms_csr2 & MS2_ADRSERR) ! 243: type = "address parity err"; ! 244: else if (mcr->ms_csr2 & MS2_RDSERR) ! 245: type = "rds err"; ! 246: else if (mcr->ms_csr2 & MS2_CRDERR) { ! 247: hard = 0; ! 248: type = ""; ! 249: } else ! 250: type = "mysterious error"; ! 251: printf("mcr%d: %s%s%s addr %x bank %x syn %x\n", m, ! 252: hard ? "hard error: " : "soft ecc", ! 253: type, mcr->ms_csr2 & MS2_HIERR ? ! 254: " (+ other rds or crd err)" : "", ! 255: ((mcr->ms_csr2 & MS2_ADDR) + mcr->biic.bi_sadr) >> 9, ! 256: (mcr->ms_csr2 & MS2_INTLVADDR) != 0, ! 257: mcr->ms_csr2 & MS2_SYN); ! 258: mcr->ms_csr1 = mcr->ms_csr1 | MS1_CRDINH; ! 259: mcr->ms_csr2 = mcr->ms_csr2; ! 260: } ! 261: } ! 262: ! 263: /* these are bits 0 to 6 in the summary field */ ! 264: char *mc8200[] = { ! 265: "cpu bad ipl", "ucode lost err", ! 266: "ucode par err", "DAL par err", ! 267: "BI bus err", "BTB tag par", ! 268: "cache tag par", ! 269: }; ! 270: #define MC8200_BADIPL 0x01 ! 271: #define MC8200_UERR 0x02 ! 272: #define MC8200_UPAR 0x04 ! 273: #define MC8200_DPAR 0x08 ! 274: #define MC8200_BIERR 0x10 ! 275: #define MC8200_BTAGPAR 0x20 ! 276: #define MC8200_CTAGPAR 0x40 ! 277: ! 278: struct mc8200frame { ! 279: int mc82_bcnt; /* byte count == 0x20 */ ! 280: int mc82_summary; /* summary parameter */ ! 281: int mc82_param1; /* parameter 1 */ ! 282: int mc82_va; /* va register */ ! 283: int mc82_vap; /* va prime register */ ! 284: int mc82_ma; /* memory address */ ! 285: int mc82_status; /* status word */ ! 286: int mc82_epc; /* error pc */ ! 287: int mc82_upc; /* micro pc */ ! 288: int mc82_pc; /* current pc */ ! 289: int mc82_psl; /* current psl */ ! 290: }; ! 291: ! 292: ka820_mchk(cmcf) ! 293: caddr_t cmcf; ! 294: { ! 295: register struct mc8200frame *mcf = (struct mc8200frame *)cmcf; ! 296: register int i, type = mcf->mc82_summary; ! 297: extern int cold; ! 298: ! 299: /* ignore BI bus errors during configuration */ ! 300: if (cold && type == MC8200_BIERR) { ! 301: mtpr(MCESR, 0xf); ! 302: return (MCHK_RECOVERED); ! 303: } ! 304: ! 305: /* ! 306: * SOME ERRORS ARE RECOVERABLE ! 307: * do it later ! 308: */ ! 309: printf("machine check %x: ", type); ! 310: for (i = 0; i < sizeof (mc8200) / sizeof (mc8200[0]); i++) ! 311: if (type & (1 << i)) ! 312: printf(" %s,", mc8200[i]); ! 313: printf(" param1 %x\n", mcf->mc82_param1); ! 314: printf( ! 315: "\tva %x va' %x ma %x pc %x psl %x\n\tstatus %x errpc %x upc %x\n", ! 316: mcf->mc82_va, mcf->mc82_vap, mcf->mc82_ma, ! 317: mcf->mc82_pc, mcf->mc82_psl, ! 318: mcf->mc82_status, mcf->mc82_epc, mcf->mc82_upc); ! 319: return (MCHK_PANIC); ! 320: } ! 321: ! 322: /* ! 323: * Receive a character from logical console. ! 324: */ ! 325: rxcdintr() ! 326: { ! 327: register int c = mfpr(RXCD); ! 328: ! 329: /* not sure what (if anything) to do with these */ ! 330: printf("rxcd node %x c=0x%x\n", (c >> 8) & 0xf, c & 0xff); ! 331: } ! 332: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.