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