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