Home | History | Annotate | Line # | Download | only in pmax
      1 /* $NetBSD: dec_5100.c,v 1.48 2014/03/24 19:31:40 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 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     33 
     34 __KERNEL_RCSID(0, "$NetBSD: dec_5100.c,v 1.48 2014/03/24 19:31:40 christos Exp $");
     35 
     36 #define __INTR_PRIVATE
     37 #include <sys/param.h>
     38 #include <sys/cpu.h>
     39 #include <sys/device.h>
     40 #include <sys/intr.h>
     41 #include <sys/lwp.h>
     42 #include <sys/kernel.h>
     43 #include <sys/systm.h>
     44 
     45 #include <mips/locore.h>
     46 
     47 #include <mips/mips/mips_mcclock.h>	/* mcclock CPUspeed estimation */
     48 
     49 #include <pmax/locore.h>
     50 #include <pmax/sysconf.h>
     51 
     52 #include <dev/tc/tcvar.h>		/* tc_addr_t */
     53 
     54 #include <pmax/pmax/machdep.h>
     55 #include <pmax/pmax/kn01.h>		/* common definitions */
     56 #include <pmax/pmax/kn230.h>
     57 
     58 #include <pmax/ibus/ibusvar.h>
     59 
     60 #include <pmax/pmax/cons.h>
     61 
     62 void		dec_5100_init(void);		/* XXX */
     63 static void	dec_5100_bus_reset(void);
     64 static void	dec_5100_cons_init(void);
     65 static void	dec_5100_intr(uint32_t, vaddr_t, uint32_t);
     66 static void	dec_5100_intr_establish(device_t, void *,
     67 		    int, int (*)(void *), void *);
     68 static void	dec_5100_memintr(void);
     69 
     70 static const struct ipl_sr_map dec_5100_ipl_sr_map = {
     71     .sr_bits = {
     72 	[IPL_NONE] = 0,
     73 	[IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0,
     74 	[IPL_SOFTNET] = MIPS_SOFT_INT_MASK,
     75 	[IPL_VM] = MIPS_SPL_0_1,
     76 	[IPL_SCHED] = MIPS_SPLHIGH,
     77 	[IPL_DDB] = MIPS_SPLHIGH,
     78 	[IPL_HIGH] = MIPS_SPLHIGH,
     79     },
     80 };
     81 
     82 void
     83 dec_5100_init(void)
     84 {
     85 
     86 	platform.iobus = "baseboard";
     87 	platform.bus_reset = dec_5100_bus_reset;
     88 	platform.cons_init = dec_5100_cons_init;
     89 	platform.iointr = dec_5100_intr;
     90 	platform.intr_establish = dec_5100_intr_establish;
     91 	platform.memsize = memsize_scan;
     92 	/* no high resolution timer available */
     93 
     94 	/* set correct wbflush routine for this motherboard */
     95 	mips_set_wbflush(kn230_wbflush);
     96 
     97 	ipl_sr_map = dec_5100_ipl_sr_map;
     98 
     99 	/* calibrate cpu_mhz value */
    100 	mc_cpuspeed(MIPS_PHYS_TO_KSEG1(KN01_SYS_CLOCK), MIPS_INT_MASK_2);
    101 
    102 	cpu_setmodel("DECsystem 5100 (MIPSMATE)");
    103 }
    104 
    105 /*
    106  * Initialize the memory system and I/O buses.
    107  */
    108 static void
    109 dec_5100_bus_reset(void)
    110 {
    111 	uint32_t icsr;
    112 
    113 	/* clear any memory error condition */
    114 	icsr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN230_SYS_ICSR);
    115 	icsr |= KN230_CSR_INTR_WMERR;
    116 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN230_SYS_ICSR) = icsr;
    117 
    118 	/* nothing else to do */
    119 	kn230_wbflush();
    120 }
    121 
    122 static void
    123 dec_5100_cons_init(void)
    124 {
    125 
    126 	/*
    127 	 * Delay to allow PROM putchars to complete.
    128 	 * FIFO depth * character time,
    129 	 * character time = (1000000 / (defaultrate / 10))
    130 	 */
    131 	DELAY(160000000 / 9600);	/* XXX */
    132 
    133 	dz_ibus_cnsetup(KN230_SYS_DZ0);
    134 	dz_ibus_cnattach(0);
    135 }
    136 
    137 static void
    138 dec_5100_intr_establish(device_t dev, void *cookie, int level,
    139     int (*handler)(void *), void *arg)
    140 {
    141 
    142 	intrtab[(intptr_t)cookie].ih_func = handler;
    143 	intrtab[(intptr_t)cookie].ih_arg = arg;
    144 }
    145 
    146 
    147 #define CALLINTR(vvv, ibit)						\
    148     do {								\
    149 	if ((icsr & (ibit)) && intrtab[vvv].ih_func) {			\
    150 		(*intrtab[vvv].ih_func)(intrtab[vvv].ih_arg);		\
    151 		intrtab[vvv].ih_count.ev_count++;			\
    152 	}								\
    153     } while (/*CONSTCOND*/0)
    154 
    155 static void
    156 dec_5100_intr(uint32_t status, vaddr_t pc, uint32_t ipending)
    157 {
    158 	uint32_t icsr;
    159 
    160 	if (ipending & MIPS_INT_MASK_4) {
    161 #ifdef DDB
    162 		Debugger();
    163 #else
    164 		prom_haltbutton();
    165 #endif
    166 	}
    167 
    168 	icsr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN230_SYS_ICSR);
    169 
    170 	/* handle clock interrupts ASAP */
    171 	if (ipending & MIPS_INT_MASK_2) {
    172 		struct clockframe cf;
    173 
    174 		__asm volatile("lbu $0,48(%0)" ::
    175 			"r"(MIPS_PHYS_TO_KSEG1(KN01_SYS_CLOCK)));
    176 		cf.pc = pc;
    177 		cf.sr = status;
    178 		cf.intr = (curcpu()->ci_idepth > 1);
    179 		hardclock(&cf);
    180 		pmax_clock_evcnt.ev_count++;
    181 	}
    182 
    183 	if (ipending & MIPS_INT_MASK_0) {
    184 		CALLINTR(SYS_DEV_SCC0, KN230_CSR_INTR_DZ0);
    185 		CALLINTR(SYS_DEV_OPT0, KN230_CSR_INTR_OPT0);
    186 		CALLINTR(SYS_DEV_OPT1, KN230_CSR_INTR_OPT1);
    187 	}
    188 
    189 	if (ipending & MIPS_INT_MASK_1) {
    190 		CALLINTR(SYS_DEV_LANCE, KN230_CSR_INTR_LANCE);
    191 		CALLINTR(SYS_DEV_SCSI, KN230_CSR_INTR_SII);
    192 	}
    193 
    194 	if (ipending & MIPS_INT_MASK_3) {
    195 		dec_5100_memintr();
    196 		pmax_memerr_evcnt.ev_count++;
    197 	}
    198 }
    199 
    200 
    201 /*
    202  * Handle write-to-nonexistent-address memory errors on MIPS_INT_MASK_3.
    203  * These are reported asynchronously, due to hardware write buffering.
    204  * we can't easily figure out process context, so just panic.
    205  *
    206  * XXX drain writebuffer on contextswitch to avoid panic?
    207  */
    208 static void
    209 dec_5100_memintr(void)
    210 {
    211 	uint32_t icsr;
    212 
    213 	/* read icsr and clear error  */
    214 	icsr = *(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN230_SYS_ICSR);
    215 	icsr |= KN230_CSR_INTR_WMERR;
    216 	*(volatile uint32_t *)MIPS_PHYS_TO_KSEG1(KN230_SYS_ICSR) = icsr;
    217 	kn230_wbflush();
    218 
    219 #ifdef DIAGNOSTIC
    220 	printf("\nMemory interrupt\n");
    221 #endif
    222 
    223 	/* ignore errors during probes */
    224 	if (cold)
    225 		return;
    226 
    227 	if (icsr & KN230_CSR_INTR_WMERR) {
    228 		panic("write to non-existent memory");
    229 	} else {
    230 		panic("stray memory error interrupt");
    231 	}
    232 }
    233