Home | History | Annotate | Line # | Download | only in pmax
      1 /* $NetBSD: dec_3max.c,v 1.56 2014/03/24 19:31:39 christos 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. Neither the name of the University nor the names of its contributors
     52  *    may be used to endorse or promote products derived from this software
     53  *    without specific prior written permission.
     54  *
     55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     65  * SUCH DAMAGE.
     66  *
     67  *	@(#)machdep.c	8.3 (Berkeley) 1/12/94
     68  */
     69 
     70 #define	__INTR_PRIVATE
     71 
     72 #include <sys/cdefs.h>
     73 __KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.56 2014/03/24 19:31:39 christos Exp $");
     74 
     75 #include "dzkbd.h"
     76 
     77 #include <sys/param.h>
     78 #include <sys/bus.h>
     79 #include <sys/cpu.h>
     80 #include <sys/device.h>
     81 #include <sys/intr.h>
     82 #include <sys/lwp.h>
     83 #include <sys/systm.h>
     84 
     85 #include <mips/locore.h>
     86 
     87 #include <mips/mips/mips_mcclock.h>	/* mcclock CPUspeed estimation */
     88 
     89 #include <dev/tc/tcvar.h>		/* tc_addr_t */
     90 
     91 #include <pmax/sysconf.h>
     92 
     93 #include <pmax/pmax/machdep.h>
     94 #include <pmax/pmax/kn02.h>
     95 #include <pmax/pmax/memc.h>
     96 
     97 #include <dev/dec/dzreg.h>
     98 #include <dev/dec/dzvar.h>
     99 #include <dev/dec/dzkbdvar.h>
    100 #include <pmax/pmax/cons.h>
    101 #include "wsdisplay.h"
    102 
    103 void		dec_3max_init(void);		/* XXX */
    104 static void	dec_3max_bus_reset(void);
    105 
    106 static void	dec_3max_cons_init(void);
    107 static void	dec_3max_errintr(void);
    108 static void	dec_3max_intr(uint32_t, vaddr_t, uint32_t);
    109 static void	dec_3max_intr_establish(device_t, void *,
    110 		    int, int (*)(void *), void *);
    111 
    112 
    113 #define	kn02_wbflush()	wbflush()	/* XXX to be corrected XXX */
    114 
    115 static const struct ipl_sr_map dec_3max_ipl_sr_map = {
    116     .sr_bits = {
    117 	[IPL_NONE] = 0,
    118 	[IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0,
    119 	[IPL_SOFTNET] = MIPS_SOFT_INT_MASK,
    120 	[IPL_VM] = MIPS_SPL0,
    121 	[IPL_SCHED] = MIPS_SPLHIGH,
    122 	[IPL_DDB] = MIPS_SPLHIGH,
    123 	[IPL_HIGH] = MIPS_SPLHIGH,
    124     },
    125 };
    126 
    127 void
    128 dec_3max_init(void)
    129 {
    130 	uint32_t csr;
    131 
    132 	platform.iobus = "tcbus";
    133 	platform.bus_reset = dec_3max_bus_reset;
    134 	platform.cons_init = dec_3max_cons_init;
    135 	platform.iointr = dec_3max_intr;
    136 	platform.intr_establish = dec_3max_intr_establish;
    137 	platform.memsize = memsize_bitmap;
    138 	/* no high resolution timer available */
    139 
    140 	/* clear any memory errors */
    141 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
    142 	kn02_wbflush();
    143 
    144 	ipl_sr_map = dec_3max_ipl_sr_map;
    145 
    146 	/* calibrate cpu_mhz value */
    147 	mc_cpuspeed(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK), MIPS_INT_MASK_1);
    148 
    149 	/*
    150 	 * Enable ECC memory correction, turn off LEDs, and
    151 	 * disable all TURBOchannel interrupts.
    152 	 */
    153 	csr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
    154 	csr &= ~(KN02_CSR_WRESERVED|KN02_CSR_IOINTEN|KN02_CSR_CORRECT|0xff);
    155 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr;
    156 	kn02_wbflush();
    157 
    158 	cpu_setmodel("DECstation 5000/200 (3MAX)");
    159 }
    160 
    161 /*
    162  * Initialize the memory system and I/O buses.
    163  */
    164 static void
    165 dec_3max_bus_reset(void)
    166 {
    167 
    168 	/*
    169 	 * Reset interrupts, clear any errors from newconf probes
    170 	 */
    171 
    172 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
    173 	kn02_wbflush();
    174 
    175 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0;
    176 	kn02_wbflush();
    177 }
    178 
    179 static void
    180 dec_3max_cons_init(void)
    181 {
    182 	int kbd, crt, screen;
    183 	extern int tcfb_cnattach(int);		/* XXX */
    184 
    185 	kbd = crt = screen = 0;
    186 	prom_findcons(&kbd, &crt, &screen);
    187 
    188 	if (screen > 0) {
    189 #if NWSDISPLAY > 0
    190  		if (kbd == 7 && tcfb_cnattach(crt) > 0) {
    191 			dz_ibus_cnsetup(KN02_SYS_DZ);
    192 			dzkbd_cnattach(NULL);
    193  			return;
    194  		}
    195 #endif
    196 		printf("No framebuffer device configured for slot %d: ", crt);
    197 		printf("using serial console\n");
    198 	}
    199 	/*
    200 	 * Delay to allow PROM putchars to complete.
    201 	 * FIFO depth * character time,
    202 	 * character time = (1000000 / (defaultrate / 10))
    203 	 */
    204 	DELAY(160000000 / 9600);	/* XXX */
    205 
    206 	dz_ibus_cnsetup(KN02_SYS_DZ);
    207 	dz_ibus_cnattach(kbd);
    208 }
    209 
    210 static const struct {
    211 	int cookie;
    212 	int intrbit;
    213 } kn02intrs[] = {
    214 	{ SYS_DEV_OPT0,	 KN02_IP_SLOT0 },
    215 	{ SYS_DEV_OPT1,	 KN02_IP_SLOT1 },
    216 	{ SYS_DEV_OPT2,	 KN02_IP_SLOT2 },
    217 	{ SYS_DEV_SCSI,	 KN02_IP_SCSI },
    218 	{ SYS_DEV_LANCE, KN02_IP_LANCE },
    219 	{ SYS_DEV_SCC0,	 KN02_IP_DZ },
    220 };
    221 
    222 static void
    223 dec_3max_intr_establish(device_t dev, void *cookie, int level,
    224     int (*handler)(void *), void *arg)
    225 {
    226 	int i;
    227 	uint32_t csr;
    228 
    229 	for (i = 0; i < __arraycount(kn02intrs); i++) {
    230 		if (kn02intrs[i].cookie == (intptr_t)cookie)
    231 			goto found;
    232 	}
    233 	panic("intr_establish: invalid cookie %p", cookie);
    234 
    235 found:
    236 	intrtab[(intptr_t)cookie].ih_func = handler;
    237 	intrtab[(intptr_t)cookie].ih_arg = arg;
    238 
    239 	csr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) &
    240 	    0x00ffff00;
    241 	csr |= (kn02intrs[i].intrbit << 16);
    242 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) = csr;
    243 }
    244 
    245 
    246 #define CALLINTR(vvv)						\
    247 	do {							\
    248 		intrtab[vvv].ih_count.ev_count++;		\
    249 		(*intrtab[vvv].ih_func)(intrtab[vvv].ih_arg);	\
    250 	} while (/*CONSTCOND*/0)
    251 
    252 static void
    253 dec_3max_intr(uint32_t status, vaddr_t pc, uint32_t ipending)
    254 {
    255 	static bool warned = false;
    256 	uint32_t csr;
    257 
    258 	/* handle clock interrupts ASAP */
    259 	if (ipending & MIPS_INT_MASK_1) {
    260 		struct clockframe cf;
    261 
    262 		csr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
    263 		if ((csr & KN02_CSR_PSWARN) && !warned) {
    264 			warned = true;
    265 			printf("WARNING: power supply is overheating!\n");
    266 		} else if (warned && !(csr & KN02_CSR_PSWARN)) {
    267 			warned = false;
    268 			printf("WARNING: power supply is OK again\n");
    269 		}
    270 
    271 		__asm volatile("lbu $0,48(%0)" ::
    272 			"r"(MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK)));
    273 		cf.pc = pc;
    274 		cf.sr = status;
    275 		cf.intr = (curcpu()->ci_idepth > 1);
    276 		hardclock(&cf);
    277 		pmax_clock_evcnt.ev_count++;
    278 
    279 		/* keep clock interrupts enabled when we return */
    280 	}
    281 
    282 	if (ipending & MIPS_INT_MASK_0) {
    283 		csr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
    284 		csr &= (csr >> KN02_CSR_IOINTEN_SHIFT);
    285 		if (csr & (KN02_IP_DZ | KN02_IP_LANCE | KN02_IP_SCSI)) {
    286 			if (csr & KN02_IP_DZ)
    287 				CALLINTR(SYS_DEV_SCC0);
    288 			if (csr & KN02_IP_LANCE)
    289 				CALLINTR(SYS_DEV_LANCE);
    290 			if (csr & KN02_IP_SCSI)
    291 				CALLINTR(SYS_DEV_SCSI);
    292 		}
    293 		if (csr & (KN02_IP_SLOT2 | KN02_IP_SLOT1 | KN02_IP_SLOT0)) {
    294 			if (csr & KN02_IP_SLOT2)
    295 				CALLINTR(SYS_DEV_OPT2);
    296 			if (csr & KN02_IP_SLOT1)
    297 				CALLINTR(SYS_DEV_OPT1);
    298 			if (csr & KN02_IP_SLOT0)
    299 				CALLINTR(SYS_DEV_OPT0);
    300 		}
    301 	}
    302 	if (ipending & MIPS_INT_MASK_3) {
    303 		dec_3max_errintr();
    304 		pmax_memerr_evcnt.ev_count++;
    305 	}
    306 }
    307 
    308 
    309 /*
    310  * Handle Memory error.   3max, 3maxplus has ECC.
    311  * Correct single-bit error, panic on double-bit error.
    312  * XXX on double-error on clean user page, mark bad and reload frame?
    313  */
    314 static void
    315 dec_3max_errintr(void)
    316 {
    317 	uint32_t erradr, csr;
    318 	vaddr_t errsyn;
    319 
    320 	/* Fetch error address, ECC chk/syn bits, clear interrupt */
    321 	erradr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR);
    322 	errsyn = MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN);
    323 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
    324 	kn02_wbflush();
    325 	csr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
    326 
    327 	/* Send to kn02/kn03 memory subsystem handler */
    328 	dec_mtasic_err(erradr, errsyn, csr & KN02_CSR_BNK32M);
    329 }
    330