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