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