Home | History | Annotate | Line # | Download | only in vax
      1 /*	$NetBSD: ka670.c,v 1.17 2017/05/22 16:46:15 ragge Exp $	*/
      2 /*
      3  * Copyright (c) 1999 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to Ludd by Bertram Barth.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: ka670.c,v 1.17 2017/05/22 16:46:15 ragge Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/systm.h>
     34 #include <sys/cpu.h>
     35 #include <sys/device.h>
     36 #include <sys/kernel.h>
     37 
     38 #include <machine/sid.h>
     39 #include <machine/nexus.h>
     40 #include <machine/vsbus.h>
     41 #include <machine/ka670.h>
     42 #include <machine/clock.h>
     43 
     44 static void ka670_memerr(void);
     45 static void ka670_conf(void);
     46 static void ka670_attach_cpu(device_t);
     47 static int ka670_mchk(void *);
     48 static int ka670_cache_init(void);	/* "int mapen" as argument? */
     49 
     50 static const char * const ka670_devs[] = { "cpu", "sgec", "shac", "uba", NULL };
     51 
     52 const struct cpu_dep ka670_calls = {
     53 	.cpu_mchk	= ka670_mchk,
     54 	.cpu_memerr	= ka670_memerr,
     55 	.cpu_conf	= ka670_conf,
     56 	.cpu_gettime	= generic_gettime,
     57 	.cpu_settime	= generic_settime,
     58 	.cpu_vups	= 8,	/* 8 VUP */
     59 	.cpu_scbsz	= 2,	/* SCB pages */
     60 	.cpu_halt	= generic_halt,
     61 	.cpu_reboot	= generic_reboot,
     62 	.cpu_devs	= ka670_devs,
     63 	.cpu_attach_cpu	= ka670_attach_cpu,
     64 };
     65 
     66 #define KA670_MC_RESTART	0x00008000	/* Restart possible*/
     67 #define KA670_PSL_FPDONE	0x00010000	/* First Part Done */
     68 
     69 struct ka670_mcframe {		/* Format of RigelMAX machine check frame: */
     70 	int	mc670_bcnt;	/* byte count, always 24 (0x18) */
     71 	int	mc670_code;	/* machine check type code and restart bit */
     72 	int	mc670_addr;	/* most recent (faulting?) virtual address */
     73 	int	mc670_viba;	/* contents of VIBA register */
     74 	int	mc670_sisr;	/* ICCS bit 6 and SISR bits 15:0 */
     75 	int	mc670_istate;	/* internal state */
     76 	int	mc670_sc;	/* shift count register */
     77 	int	mc670_pc;	/* trapped PC */
     78 	int	mc670_psl;	/* trapped PSL */
     79 };
     80 
     81 #if 0
     82 
     83 /*
     84  * This is not the mchk types on KA670.
     85  */
     86 static const char * const ka670_mctype[] = {
     87 	"no error (0)",			/* Code 0: No error */
     88 	"FPA: protocol error",		/* Code 1-5: FPA errors */
     89 	"FPA: illegal opcode",
     90 	"FPA: operand parity error",
     91 	"FPA: unknown status",
     92 	"FPA: result parity error",
     93 	"unused (6)",			/* Code 6-7: Unused */
     94 	"unused (7)",
     95 	"MMU error (TLB miss)",		/* Code 8-9: MMU errors */
     96 	"MMU error (TLB hit)",
     97 	"HW interrupt at unused IPL",	/* Code 10: Interrupt error */
     98 	"MOVCx impossible state",	/* Code 11-13: Microcode errors */
     99 	"undefined trap code (i-box)",
    100 	"undefined control store address",
    101 	"unused (14)",			/* Code 14-15: Unused */
    102 	"unused (15)",
    103 	"PC tag or data parity error",	/* Code 16: Cache error */
    104 	"data bus parity error",	/* Code 17: Read error */
    105 	"data bus error (NXM)",		/* Code 18: Write error */
    106 	"undefined data bus state",	/* Code 19: Bus error */
    107 };
    108 #define MC670_MAX	19
    109 #endif
    110 
    111 static int ka670_error_count = 0;
    112 
    113 int
    114 ka670_mchk(void *addr)
    115 {
    116 	struct ka670_mcframe * const mcf = addr;
    117 
    118 	mtpr(0x00, PR_MCESR);	/* Acknowledge the machine check */
    119 	printf("machine check %d (0x%x)\n", mcf->mc670_code, mcf->mc670_code);
    120 	printf("PC %x PSL %x\n", mcf->mc670_pc, mcf->mc670_psl);
    121 	if (++ka670_error_count > 10) {
    122 		printf("error_count exceeded: %d\n", ka670_error_count);
    123 		return (-1);
    124 	}
    125 
    126 	/*
    127 	 * If either the Restart flag is set or the First-Part-Done flag
    128 	 * is set, and the TRAP2 (double error) bit is not set, then the
    129 	 * error is recoverable.
    130 	 */
    131 	if (mfpr(PR_PCSTS) & KA670_PCS_TRAP2) {
    132 		printf("TRAP2 (double error) in ka670_mchk.\n");
    133 		panic("unrecoverable state in ka670_mchk.");
    134 		return (-1);
    135 	}
    136 	if ((mcf->mc670_code & KA670_MC_RESTART) ||
    137 	    (mcf->mc670_psl & KA670_PSL_FPDONE)) {
    138 		printf("ka670_mchk: recovering from machine-check.\n");
    139 		ka670_cache_init();	/* reset caches */
    140 		return (0);		/* go on; */
    141 	}
    142 
    143 	/*
    144 	 * Unknown error state, panic/halt the machine!
    145 	 */
    146 	printf("ka670_mchk: unknown error state!\n");
    147 	return (-1);
    148 }
    149 
    150 void
    151 ka670_memerr(void)
    152 {
    153 	char sbuf[256];
    154 
    155 	/*
    156 	 * Don\'t know what to do here. So just print some messages
    157 	 * and try to go on...
    158 	 */
    159 
    160 	printf("memory error!\n");
    161 
    162 	snprintb(sbuf, sizeof(sbuf), KA670_PCSTS_BITS, mfpr(PR_PCSTS));
    163 	printf("primary cache status: %s\n", sbuf);
    164 
    165 	snprintb(sbuf, sizeof(sbuf), KA670_BCSTS_BITS, mfpr(PR_BCSTS));
    166 	printf("secondary cache status: %s\n", sbuf);
    167 }
    168 
    169 int
    170 ka670_cache_init(void)
    171 {
    172 	int val;
    173 #ifdef DEBUG
    174 	char sbuf[256];
    175 #endif
    176 
    177 	mtpr(KA670_PCS_REFRESH, PR_PCSTS);	/* disable primary cache */
    178 	val = mfpr(PR_PCSTS);
    179 	mtpr(val, PR_PCSTS);			/* clear error flags */
    180 	mtpr(8, PR_BCCTL);			/* disable backup cache */
    181 	mtpr(0, PR_BCFBTS);	/* flush backup cache tag store */
    182 	mtpr(0, PR_BCFPTS);	/* flush primary cache tag store */
    183 	mtpr(0x0e, PR_BCCTL);	/* enable backup cache */
    184 	mtpr(KA670_PCS_FLUSH | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
    185 	mtpr(KA670_PCS_ENABLE | KA670_PCS_REFRESH, PR_PCSTS);	/* flush primary cache */
    186 
    187 #ifdef DEBUG
    188 	snprintb(sbuf, sizeof(sbuf), KA670_PCSTS_BITS, mfpr(PR_PCSTS));
    189 	printf("primary cache status: %s\n", sbuf);
    190 
    191 	snprintb(sbuf, sizeof(sbuf), KA670_BCSTS_BITS, mfpr(PR_BCSTS));
    192 	printf("secondary cache status: %s\n", sbuf);
    193 #endif
    194 
    195 	return (0);
    196 }
    197 
    198 void
    199 ka670_conf(void)
    200 {
    201 
    202 	/*
    203 	 * ka670_conf() gets called with MMU enabled, now it's save to
    204 	 * init/reset the caches.
    205 	 */
    206 	ka670_cache_init();
    207 
    208 	cpmbx = (struct cpmbx *)vax_map_physmem(0x20140400, 1);
    209 }
    210 
    211 void
    212 ka670_attach_cpu(device_t self)
    213 {
    214 	aprint_normal(
    215 	    ": %s, Rigel (ucode rev %d), 2KB L1 cache, 128KB L2 cache\n",
    216 	    "KA670",
    217 	    vax_cpudata % 0377);
    218 }
    219