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