1 /* $NetBSD: dec_3max.c,v 1.37 2001/09/18 16:24:16 tsutsui Exp $ */ 2 3 /* 4 * Copyright (c) 1998 Jonathan Stone. 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 Jonathan Stone for 17 * the NetBSD Project. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1988 University of Utah. 35 * Copyright (c) 1992, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * the Systems Programming Group of the University of Utah Computer 40 * Science Department, The Mach Operating System project at 41 * Carnegie-Mellon University and Ralph Campbell. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by the University of 54 * California, Berkeley and its contributors. 55 * 4. Neither the name of the University nor the names of its contributors 56 * may be used to endorse or promote products derived from this software 57 * without specific prior written permission. 58 * 59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 72 */ 73 74 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 75 76 __KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.37 2001/09/18 16:24:16 tsutsui Exp $"); 77 78 #include <sys/param.h> 79 #include <sys/systm.h> 80 #include <sys/device.h> 81 82 #include <machine/cpu.h> 83 #include <machine/intr.h> 84 #include <machine/locore.h> 85 #include <machine/sysconf.h> 86 87 #include <mips/mips/mips_mcclock.h> /* mcclock CPUspeed estimation */ 88 89 #include <pmax/pmax/machdep.h> 90 #include <pmax/pmax/kn02.h> 91 #include <pmax/pmax/memc.h> 92 #include <pmax/dev/dcvar.h> 93 94 #include "rasterconsole.h" 95 96 void dec_3max_init __P((void)); /* XXX */ 97 static void dec_3max_bus_reset __P((void)); 98 99 static void dec_3max_cons_init __P((void)); 100 static void dec_3max_errintr __P((void)); 101 static void dec_3max_intr __P((unsigned, unsigned, unsigned, unsigned)); 102 static void dec_3max_intr_establish __P((struct device *, void *, 103 int, int (*)(void *), void *)); 104 105 106 #define kn02_wbflush() mips1_wbflush() /* XXX to be corrected XXX */ 107 108 void 109 dec_3max_init() 110 { 111 u_int32_t csr; 112 113 platform.iobus = "tcbus"; 114 platform.bus_reset = dec_3max_bus_reset; 115 platform.cons_init = dec_3max_cons_init; 116 platform.iointr = dec_3max_intr; 117 platform.intr_establish = dec_3max_intr_establish; 118 platform.memsize = memsize_bitmap; 119 /* no high resolution timer available */ 120 121 /* clear any memory errors */ 122 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0; 123 kn02_wbflush(); 124 125 splvec.splbio = MIPS_SPL0; 126 splvec.splnet = MIPS_SPL0; 127 splvec.spltty = MIPS_SPL0; 128 splvec.splvm = MIPS_SPL0; 129 splvec.splclock = MIPS_SPL_0_1; 130 splvec.splstatclock = MIPS_SPL_0_1; 131 132 /* calibrate cpu_mhz value */ 133 mc_cpuspeed(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK), MIPS_INT_MASK_1); 134 135 /* 136 * Enable ECC memory correction, turn off LEDs, and 137 * disable all TURBOchannel interrupts. 138 */ 139 csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR); 140 csr &= ~(KN02_CSR_WRESERVED|KN02_CSR_IOINTEN|KN02_CSR_CORRECT|0xff); 141 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr; 142 kn02_wbflush(); 143 144 strcpy(cpu_model, "DECstation 5000/200 (3MAX)"); 145 } 146 147 /* 148 * Initialize the memory system and I/O buses. 149 */ 150 static void 151 dec_3max_bus_reset() 152 { 153 /* 154 * Reset interrupts, clear any errors from newconf probes 155 */ 156 157 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0; 158 kn02_wbflush(); 159 160 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0; 161 kn02_wbflush(); 162 } 163 164 static void 165 dec_3max_cons_init() 166 { 167 int kbd, crt, screen; 168 extern int tcfb_cnattach __P((int)); /* XXX */ 169 170 kbd = crt = screen = 0; 171 prom_findcons(&kbd, &crt, &screen); 172 173 if (screen > 0) { 174 #if NRASTERCONSOLE > 0 175 if (kbd == 7 && tcfb_cnattach(crt) > 0) { 176 dckbd_cnattach(KN02_SYS_DZ); 177 return; 178 } 179 #else 180 printf("No framebuffer device configured for slot %d: ", crt); 181 printf("using serial console\n"); 182 #endif 183 } 184 /* 185 * Delay to allow PROM putchars to complete. 186 * FIFO depth * character time, 187 * character time = (1000000 / (defaultrate / 10)) 188 */ 189 DELAY(160000000 / 9600); /* XXX */ 190 191 dc_cnattach(KN02_SYS_DZ, kbd); 192 } 193 194 static const struct { 195 int cookie; 196 int intrbit; 197 } kn02intrs[] = { 198 { SYS_DEV_OPT0, KN02_IP_SLOT0 }, 199 { SYS_DEV_OPT1, KN02_IP_SLOT1 }, 200 { SYS_DEV_OPT2, KN02_IP_SLOT2 }, 201 { SYS_DEV_SCSI, KN02_IP_SCSI }, 202 { SYS_DEV_LANCE, KN02_IP_LANCE }, 203 { SYS_DEV_SCC0, KN02_IP_DZ }, 204 }; 205 206 static void 207 dec_3max_intr_establish(dev, cookie, level, handler, arg) 208 struct device *dev; 209 void *cookie; 210 int level; 211 int (*handler) __P((void *)); 212 void *arg; 213 { 214 int i; 215 u_int32_t csr; 216 217 for (i = 0; i < sizeof(kn02intrs)/sizeof(kn02intrs[0]); i++) { 218 if (kn02intrs[i].cookie == (int)cookie) 219 goto found; 220 } 221 panic("intr_establish: invalid cookie %d", (int)cookie); 222 223 found: 224 intrtab[(int)cookie].ih_func = handler; 225 intrtab[(int)cookie].ih_arg = arg; 226 227 csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) & 0x00ffff00; 228 csr |= (kn02intrs[i].intrbit << 16); 229 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr; 230 kn02_wbflush(); 231 } 232 233 234 #define CALLINTR(vvv) \ 235 do { \ 236 intrcnt[vvv] += 1; \ 237 (*intrtab[vvv].ih_func)(intrtab[vvv].ih_arg); \ 238 } while (0) 239 240 static void 241 dec_3max_intr(status, cause, pc, ipending) 242 unsigned status; 243 unsigned cause; 244 unsigned pc; 245 unsigned ipending; 246 { 247 static int warned = 0; 248 u_int32_t csr; 249 250 /* handle clock interrupts ASAP */ 251 if (ipending & MIPS_INT_MASK_1) { 252 struct clockframe cf; 253 254 csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR); 255 if ((csr & KN02_CSR_PSWARN) && !warned) { 256 warned = 1; 257 printf("WARNING: power supply is overheating!\n"); 258 } else if (warned && !(csr & KN02_CSR_PSWARN)) { 259 warned = 0; 260 printf("WARNING: power supply is OK again\n"); 261 } 262 263 __asm __volatile("lbu $0,48(%0)" :: 264 "r"(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK))); 265 cf.pc = pc; 266 cf.sr = status; 267 hardclock(&cf); 268 pmax_clock_evcnt.ev_count++; 269 270 /* keep clock interrupts enabled when we return */ 271 cause &= ~MIPS_INT_MASK_1; 272 } 273 274 /* If clock interrupts were enabled, re-enable them ASAP. */ 275 _splset(MIPS_SR_INT_IE | (status & MIPS_INT_MASK_1)); 276 277 if (ipending & MIPS_INT_MASK_0) { 278 csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR); 279 csr &= (csr >> KN02_CSR_IOINTEN_SHIFT); 280 if (csr & (KN02_IP_DZ | KN02_IP_LANCE | KN02_IP_SCSI)) { 281 if (csr & KN02_IP_DZ) 282 CALLINTR(SYS_DEV_SCC0); 283 if (csr & KN02_IP_LANCE) 284 CALLINTR(SYS_DEV_LANCE); 285 if (csr & KN02_IP_SCSI) 286 CALLINTR(SYS_DEV_SCSI); 287 } 288 if (csr & (KN02_IP_SLOT2 | KN02_IP_SLOT1 | KN02_IP_SLOT0)) { 289 if (csr & KN02_IP_SLOT2) 290 CALLINTR(SYS_DEV_OPT2); 291 if (csr & KN02_IP_SLOT1) 292 CALLINTR(SYS_DEV_OPT1); 293 if (csr & KN02_IP_SLOT0) 294 CALLINTR(SYS_DEV_OPT0); 295 } 296 } 297 if (ipending & MIPS_INT_MASK_3) { 298 dec_3max_errintr(); 299 pmax_memerr_evcnt.ev_count++; 300 } 301 302 _splset(MIPS_SR_INT_IE | (status & ~cause & MIPS_HARD_INT_MASK)); 303 } 304 305 306 /* 307 * Handle Memory error. 3max, 3maxplus has ECC. 308 * Correct single-bit error, panic on double-bit error. 309 * XXX on double-error on clean user page, mark bad and reload frame? 310 */ 311 static void 312 dec_3max_errintr() 313 { 314 u_int32_t erradr, errsyn, csr; 315 316 /* Fetch error address, ECC chk/syn bits, clear interrupt */ 317 erradr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR); 318 errsyn = MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN); 319 *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0; 320 kn02_wbflush(); 321 csr = *(u_int32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR); 322 323 /* Send to kn02/kn03 memory subsystem handler */ 324 dec_mtasic_err(erradr, errsyn, csr & KN02_CSR_BNK32M); 325 } 326