Home | History | Annotate | Line # | Download | only in vax
      1 /*	$NetBSD: ka750.c,v 1.47 2017/05/22 16:46:15 ragge Exp $ */
      2 /*
      3  * Copyright (c) 1982, 1986, 1988 The Regents of the University of California.
      4  * 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. Neither the name of the University nor the names of its contributors
     15  *    may be used to endorse or promote products derived from this software
     16  *    without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  *
     30  *	@(#)ka750.c	7.4 (Berkeley) 5/9/91
     31  *	@(#)autoconf.c	7.20 (Berkeley) 5/9/91
     32  */
     33 
     34 /*
     35  * Copyright (c) 1994 Ludd, University of Lule}, Sweden.
     36  * All rights reserved.
     37  *
     38  * Redistribution and use in source and binary forms, with or without
     39  * modification, are permitted provided that the following conditions
     40  * are met:
     41  * 1. Redistributions of source code must retain the above copyright
     42  *    notice, this list of conditions and the following disclaimer.
     43  * 2. Redistributions in binary form must reproduce the above copyright
     44  *    notice, this list of conditions and the following disclaimer in the
     45  *    documentation and/or other materials provided with the distribution.
     46  *
     47  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     48  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     50  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     51  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     52  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     53  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     54  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     55  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     56  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     57  * SUCH DAMAGE.
     58  *
     59  */
     60 
     61 #include <sys/cdefs.h>
     62 __KERNEL_RCSID(0, "$NetBSD: ka750.c,v 1.47 2017/05/22 16:46:15 ragge Exp $");
     63 
     64 #include <sys/param.h>
     65 #include <sys/systm.h>
     66 #include <sys/bus.h>
     67 #include <sys/cpu.h>
     68 #include <sys/device.h>
     69 
     70 #include <machine/ka750.h>
     71 #include <machine/clock.h>
     72 #include <machine/sid.h>
     73 
     74 #include <vax/vax/gencons.h>
     75 
     76 #include "locators.h"
     77 
     78 void	ctuattach(void);
     79 static	void ka750_clrf(void);
     80 static	void ka750_conf(void);
     81 static	void ka750_memerr(void);
     82 static	int ka750_mchk(void *);
     83 static	void ka750_attach_cpu(device_t);
     84 
     85 static const char * const ka750_devs[] = { "cpu", "cmi", NULL };
     86 
     87 const struct cpu_dep ka750_calls = {
     88 	.cpu_mchk	= ka750_mchk,
     89 	.cpu_memerr	= ka750_memerr,
     90 	.cpu_conf	= ka750_conf,
     91 	.cpu_gettime	= generic_gettime,
     92 	.cpu_settime	= generic_settime,
     93 	.cpu_vups	= 1,	/* ~VUPS */
     94 	.cpu_scbsz	= 4,	/* SCB pages */
     95 	.cpu_clrf	= ka750_clrf,
     96 	.cpu_devs	= ka750_devs,
     97 	.cpu_attach_cpu	= ka750_attach_cpu,
     98 };
     99 
    100 static	void *mcraddr[4];	/* XXX */
    101 
    102 void
    103 ka750_conf(void)
    104 {
    105 	if (mfpr(PR_TODR) == 0) { /* Check for failing battery */
    106 		mtpr(1, PR_TODR);
    107 		printf("WARNING: TODR battery broken\n");
    108 	}
    109 
    110 	/* Call ctuattach() here so it can setup its vectors. */
    111 	ctuattach();
    112 }
    113 
    114 void
    115 ka750_attach_cpu(device_t self)
    116 {
    117 	aprint_normal(": KA750, 4KB L1 cache, hardware/ucode rev %d/%d, ",
    118 	    V750HARDW(vax_cpudata), V750UCODE(vax_cpudata));
    119 	if (mfpr(PR_ACCS) & 255) {
    120 		aprint_normal("FPA present\n");
    121 		mtpr(0x8000, PR_ACCS);
    122 	} else {
    123 		aprint_normal("no FPA\n");
    124 	}
    125 }
    126 
    127 static int ka750_memmatch(device_t, cfdata_t, void *);
    128 static void ka750_memenable(device_t, device_t, void *);
    129 
    130 CFATTACH_DECL_NEW(mem_cmi, 0,
    131     ka750_memmatch, ka750_memenable, NULL, NULL);
    132 
    133 int
    134 ka750_memmatch(device_t parent, cfdata_t cf, void *aux)
    135 {
    136 	struct sbi_attach_args * const sa = aux;
    137 
    138 	if (cf->cf_loc[CMICF_TR] != sa->sa_nexnum &&
    139 	    cf->cf_loc[CMICF_TR] > CMICF_TR_DEFAULT)
    140 		return 0;
    141 
    142 	if (sa->sa_type != NEX_MEM16)
    143 		return 0;
    144 
    145 	return 1;
    146 }
    147 
    148 struct	mcr750 {
    149 	int	mc_err;			/* error bits */
    150 	int	mc_inh;			/* inhibit crd */
    151 	int	mc_inf;			/* info bits */
    152 };
    153 
    154 #define M750_ICRD	0x10000000	/* inhibit crd interrupts, in [1] */
    155 #define M750_UNCORR	0xc0000000	/* uncorrectable error, in [0] */
    156 #define M750_CORERR	0x20000000	/* correctable error, in [0] */
    157 
    158 #define M750_INH(mcr)	((mcr)->mc_inh = 0)
    159 #define M750_ENA(mcr)	((mcr)->mc_err = (M750_UNCORR|M750_CORERR), \
    160 			 (mcr)->mc_inh = M750_ICRD)
    161 #define M750_ERR(mcr)	((mcr)->mc_err & (M750_UNCORR|M750_CORERR))
    162 
    163 #define M750_SYN(err)	((err) & 0x7f)
    164 #define M750_ADDR(err)	(((err) >> 9) & 0x7fff)
    165 
    166 /* enable crd interrupts */
    167 void
    168 ka750_memenable(device_t parent, device_t self, void *aux)
    169 {
    170 	struct sbi_attach_args * const sa = aux;
    171 	struct mcr750 * const mcr = (struct mcr750 *)sa->sa_ioh;
    172 	int k, l, m, cardinfo;
    173 
    174 	mcraddr[device_unit(self)] = (void *)sa->sa_ioh;
    175 
    176 	/* We will use this info for error reporting - later! */
    177 	cardinfo = mcr->mc_inf;
    178 	switch ((cardinfo >> 24) & 3) {
    179 	case 0: printf(": L0011 ");
    180 		break;
    181 
    182 	case 1: printf(": L0016 ");
    183 		m = cardinfo & 0xaaaa;
    184 		for (k = l = 0; k < 16; k++){
    185 			if (m & 1)
    186 				l++;
    187 			m >>= 1;
    188 		}
    189 		printf("with %d M8750",l);
    190 		break;
    191 
    192 	case 3: printf(": L0022 ");
    193 		m = cardinfo & 0x5555;
    194 		for (k = l = 0; k < 16; k++) {
    195 			if (m & 1)
    196 				l++;
    197 			m>>=1;
    198 		}
    199 		printf("with %d M7199",l);
    200 		m = cardinfo & 0xaaaa;
    201 		if (m) {
    202 			for (k = l = 0; k < 16; k++) {
    203 				if (m & 1)
    204 					l++;
    205 				m >>= 1;
    206 			}
    207 			printf(" and %d M8750",l);
    208 		}
    209 		break;
    210 	}
    211 	printf("\n");
    212 
    213 
    214 	M750_ENA((struct mcr750 *)mcraddr[0]);
    215 }
    216 
    217 /* log crd errors */
    218 void
    219 ka750_memerr(void)
    220 {
    221 	struct mcr750 * const mcr = (struct mcr750 *)mcraddr[0];
    222 	int err;
    223 
    224 	if (M750_ERR(mcr)) {
    225 		err = mcr->mc_err;	/* careful with i/o space refs */
    226 		printf("mcr0: %s", err & M750_UNCORR ?
    227 		    "hard error" : "soft ecc");
    228 		printf(" addr %x syn %x\n", M750_ADDR(err), M750_SYN(err));
    229 		M750_INH(mcr);
    230 	}
    231 }
    232 
    233 const char mc750[][3] = {
    234 	"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"
    235 };
    236 
    237 struct mc750frame {
    238 	int	mc5_bcnt;		/* byte count == 0x28 */
    239 	int	mc5_summary;		/* summary parameter (as above) */
    240 	int	mc5_va;			/* virtual address register */
    241 	int	mc5_errpc;		/* error pc */
    242 	int	mc5_mdr;
    243 	int	mc5_svmode;		/* saved mode register */
    244 	int	mc5_rdtimo;		/* read lock timeout */
    245 	int	mc5_tbgpar;		/* tb group parity error register */
    246 	int	mc5_cacherr;		/* cache error register */
    247 	int	mc5_buserr;		/* bus error register */
    248 	int	mc5_mcesr;		/* machine check status register */
    249 	int	mc5_pc;			/* trapped pc */
    250 	int	mc5_psl;		/* trapped psl */
    251 };
    252 
    253 #define MC750_TBERR	2		/* type code of cp tbuf par */
    254 #define MC750_TBPAR	4		/* tbuf par bit in mcesr */
    255 
    256 int
    257 ka750_mchk(void *cmcf)
    258 {
    259 	register struct mc750frame *mcf = (struct mc750frame *)cmcf;
    260 	register int type = mcf->mc5_summary;
    261 	int mcsr = mfpr(PR_MCSR);
    262 
    263 	printf("machine check %x: %s%s\n", type, mc750[type&0xf],
    264 	    (type&0xf0) ? " abort" : " fault");
    265 	printf(
    266 "\tva %x errpc %x mdr %x smr %x rdtimo %x tbgpar %x cacherr %x\n",
    267 	    mcf->mc5_va, mcf->mc5_errpc, mcf->mc5_mdr, mcf->mc5_svmode,
    268 	    mcf->mc5_rdtimo, mcf->mc5_tbgpar, mcf->mc5_cacherr);
    269 	printf("\tbuserr %x mcesr %x pc %x psl %x mcsr %x\n",
    270 	    mcf->mc5_buserr, mcf->mc5_mcesr, mcf->mc5_pc, mcf->mc5_psl,
    271 	    mcsr);
    272 	mtpr(0, PR_TBIA);
    273 	mtpr(0xf, PR_MCESR);
    274 	if (type == MC750_TBERR && (mcf->mc5_mcesr&0xe) == MC750_TBPAR) {
    275 		printf("tbuf par: flushing and returning\n");
    276 		return (MCHK_RECOVERED);
    277 	}
    278 	return (MCHK_PANIC);
    279 }
    280 
    281 void
    282 ka750_clrf(void)
    283 {
    284 	int s = splhigh();
    285 
    286 #define WAIT	while ((mfpr(PR_TXCS) & GC_RDY) == 0) ;
    287 
    288 	WAIT;
    289 
    290 	mtpr(GC_CWFL|GC_CONS, PR_TXDB);
    291 
    292 	WAIT;
    293 	mtpr(GC_CCFL|GC_CONS, PR_TXDB);
    294 
    295 	WAIT;
    296 	splx(s);
    297 }
    298