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