1 /* $NetBSD: ka680.c,v 1.8 2002/09/28 09:53:08 ragge Exp $ */ 2 /* 3 * Copyright (c) 2002 Hugh Graham. 4 * Copyright (c) 2000 Ludd, University of Lule}, Sweden. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed at Ludd, University of 18 * Lule}, Sweden and its contributors. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* Done by Michael Kukat (michael@unixiron.org) */ 35 /* minor modifications for KA690 cache support by isildur@vaxpower.org */ 36 37 #include <sys/param.h> 38 #include <sys/types.h> 39 #include <sys/device.h> 40 #include <sys/kernel.h> 41 #include <sys/systm.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/nexus.h> 48 #include <machine/uvax.h> 49 #include <machine/ka680.h> 50 #include <machine/clock.h> 51 #include <machine/scb.h> 52 53 static void ka680_conf __P((void)); 54 static void ka680_cache_enable __P((void)); 55 static void ka680_softmem __P((void *)); 56 static void ka680_hardmem __P((void *)); 57 static void ka680_steal_pages __P((void)); 58 static void ka680_memerr __P((void)); 59 static int ka680_mchk __P((caddr_t)); 60 61 /* 62 * KA680-specific IPRs. KA680 has the funny habit to control all caches 63 * via IPRs. 64 */ 65 #define PR_CCTL 0xa0 66 #define CCTL_ENABLE 0x00000001 67 #define CCTL_SW_ETM 0x40000000 68 #define CCTL_HW_ETM 0x80000000 69 70 #define PR_BCETSTS 0xa3 71 #define PR_BCEDSTS 0xa6 72 #define PR_NESTS 0xae 73 74 #define PR_VMAR 0xd0 75 #define PR_VTAG 0xd1 76 #define PR_ICSR 0xd3 77 #define ICSR_ENABLE 0x01 78 79 #define PR_PCCTL 0xf8 80 #define PCCTL_P_EN 0x10 81 #define PCCTL_I_EN 0x02 82 #define PCCTL_D_EN 0x01 83 84 85 /* 86 * Declaration of KA680-specific calls. 87 */ 88 struct cpu_dep ka680_calls = { 89 ka680_steal_pages, 90 ka680_mchk, 91 ka680_memerr, 92 ka680_conf, 93 generic_clkread, 94 generic_clkwrite, 95 24, /* ~VUPS */ 96 2, /* SCB pages */ 97 generic_halt, 98 generic_reboot, 99 NULL, 100 NULL, 101 CPU_RAISEIPL, 102 }; 103 104 105 void 106 ka680_conf() 107 { 108 char *cpuname; 109 110 /* Don't ask why, but we seem to need this... */ 111 112 volatile int *hej = (void *)mfpr(PR_ISP); 113 *hej = *hej; 114 hej[-1] = hej[-1]; 115 116 cpmbx = (struct cpmbx *)vax_map_physmem(0x20140400, 1); 117 118 switch(vax_boardtype) { 119 case VAX_BTYP_680: switch((vax_siedata & 0xff00) >> 8) { 120 case VAX_STYP_675: cpuname = "KA675"; break; 121 case VAX_STYP_680: cpuname = "KA680"; break; 122 case VAX_STYP_690: cpuname = "KA690"; break; 123 default: cpuname = "unknown KA680-class"; 124 } break; 125 case VAX_BTYP_681: switch((vax_siedata & 0xff00) >> 8) { 126 case VAX_STYP_681: cpuname = "KA681"; break; 127 case VAX_STYP_691: cpuname = "KA691"; break; 128 case VAX_STYP_694: cpuname = "KA694"; break; 129 default: cpuname = "unknown KA681-class"; 130 } break; 131 default: cpuname = "unknown NVAX class"; 132 } 133 134 printf("cpu0: %s, ucode rev %d\n", cpuname, vax_cpudata & 0xff); 135 } 136 137 void 138 ka680_cache_enable() 139 { 140 int start, pslut, fslut, cslut, havevic; 141 142 /* 143 * Turn caches off. 144 */ 145 mtpr(0, PR_ICSR); 146 mtpr(0, PR_PCCTL); 147 mtpr(mfpr(PR_CCTL) | CCTL_SW_ETM, PR_CCTL); 148 149 /* 150 * Invalidate caches. 151 */ 152 mtpr(mfpr(PR_CCTL) | 6, PR_CCTL); /* Set cache size and speed */ 153 mtpr(mfpr(PR_BCETSTS), PR_BCETSTS); /* Clear error bits */ 154 mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS); /* Clear error bits */ 155 mtpr(mfpr(PR_NESTS), PR_NESTS); /* Clear error bits */ 156 157 158 start = 0x01400000; 159 /* fallback, use smallest known cache on unknown models */ 160 fslut = 0x01420000; 161 cslut = 0x01020000; 162 havevic = 0; 163 164 switch(vax_boardtype) { 165 case VAX_BTYP_680: 166 switch((vax_siedata & 0xff00) >> 8) { 167 case VAX_STYP_675: 168 fslut = 0x01420000; 169 cslut = 0x01020000; 170 havevic = 0; 171 break; 172 case VAX_STYP_680: 173 fslut = 0x01420000; 174 cslut = 0x01020000; 175 havevic = 1; 176 break; 177 case VAX_STYP_690: 178 fslut = 0x01440000; 179 cslut = 0x01040000; 180 havevic = 1; 181 break; 182 } 183 case VAX_BTYP_681: 184 switch((vax_siedata & 0xff00) >> 8) { 185 case VAX_STYP_681: 186 fslut = 0x01420000; 187 cslut = 0x01020000; 188 havevic = 1; 189 break; 190 case VAX_STYP_691: 191 fslut = 0x01420000; 192 cslut = 0x01020000; 193 havevic = 1; 194 break; 195 case VAX_STYP_694: 196 fslut = 0x01440000; 197 cslut = 0x01040000; 198 havevic = 1; 199 break; 200 } 201 } 202 203 /* Flush cache lines */ 204 for (; start < fslut; start += 0x20) 205 mtpr(0, start); 206 207 mtpr((mfpr(PR_CCTL) & ~(CCTL_SW_ETM|CCTL_ENABLE)) | CCTL_HW_ETM, 208 PR_CCTL); 209 210 start = 0x01000000; 211 212 /* clear tag and valid */ 213 for (; start < cslut; start += 0x20) 214 mtpr(0, start); 215 216 mtpr(mfpr(PR_CCTL) | 6 | CCTL_ENABLE, PR_CCTL); /* enab. bcache */ 217 218 start = 0x01800000; 219 pslut = 0x01802000; 220 221 /* Clear primary cache */ 222 for (; start < pslut; start += 0x20) 223 mtpr(0, start); 224 225 /* Flush the pipes (via REI) */ 226 asm("movpsl -(%sp); movab 1f,-(%sp); rei; 1:;"); 227 228 /* Enable primary cache */ 229 mtpr(PCCTL_P_EN|PCCTL_I_EN|PCCTL_D_EN, PR_PCCTL); 230 231 /* Enable the VIC */ 232 if (havevic) { 233 int slut; 234 235 start = 0; 236 slut = 0x800; 237 for (; start < slut; start += 0x20) { 238 mtpr(start, PR_VMAR); 239 mtpr(0, PR_VTAG); 240 } 241 mtpr(ICSR_ENABLE, PR_ICSR); 242 } 243 } 244 245 /* 246 * Why may we get memory errors during startup??? 247 */ 248 249 void 250 ka680_hardmem(void *arg) 251 { 252 if (cold == 0) 253 printf("Hard memory error\n"); 254 splhigh(); 255 } 256 257 void 258 ka680_softmem(void *arg) 259 { 260 if (cold == 0) 261 printf("Soft memory error\n"); 262 splhigh(); 263 } 264 265 void 266 ka680_steal_pages() 267 { 268 /* 269 * Get the soft and hard memory error vectors now. 270 */ 271 scb_vecalloc(0x54, ka680_softmem, NULL, 0, NULL); 272 scb_vecalloc(0x60, ka680_hardmem, NULL, 0, NULL); 273 274 /* Turn on caches (to speed up execution a bit) */ 275 ka680_cache_enable(); 276 } 277 278 void 279 ka680_memerr() 280 { 281 printf("Memory err!\n"); 282 } 283 284 int 285 ka680_mchk(caddr_t addr) 286 { 287 panic("Machine check"); 288 return 0; 289 } 290