1 /* 2 * Copyright (c) 1999 Ludd, University of Lule}, Sweden. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: ka49.c,v 1.20 2017/05/22 16:46:15 ragge Exp $"); 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/cpu.h> 32 #include <sys/device.h> 33 #include <sys/kernel.h> 34 35 #include <machine/clock.h> 36 #include <machine/scb.h> 37 #include <machine/mainbus.h> 38 39 #define KA49_CPMBX 0x38 40 #define KA49_HLT_HALT 0xcf 41 #define KA49_HLT_BOOT 0x8b 42 43 static void ka49_conf(void); 44 static void ka49_memerr(void); 45 static int ka49_mchk(void *); 46 static void ka49_halt(void); 47 static void ka49_reboot(int); 48 static void ka49_softmem(void *); 49 static void ka49_hardmem(void *); 50 static void ka49_steal_pages(void); 51 static void ka49_cache_enable(void); 52 static void ka49_halt(void); 53 54 static const char * const ka49_devs[] = { "cpu", "sgec", "vsbus", NULL }; 55 56 /* 57 * Declaration of 49-specific calls. 58 */ 59 const struct cpu_dep ka49_calls = { 60 .cpu_steal_pages = ka49_steal_pages, 61 .cpu_mchk = ka49_mchk, 62 .cpu_memerr = ka49_memerr, 63 .cpu_conf = ka49_conf, 64 .cpu_gettime = chip_gettime, 65 .cpu_settime = chip_settime, 66 .cpu_vups = 32, /* ~VUPS */ 67 .cpu_scbsz = 2, /* SCB pages */ 68 .cpu_halt = ka49_halt, 69 .cpu_reboot = ka49_reboot, 70 .cpu_devs = ka49_devs, 71 .cpu_flags = CPU_RAISEIPL, 72 }; 73 74 void 75 ka49_conf(void) 76 { 77 curcpu()->ci_cpustr = "KA49, NVAX, 10KB L1 cache, 256KB L2 cache"; 78 79 /* Why??? */ 80 { volatile int *hej = (void *)mfpr(PR_ISP); *hej = *hej; hej[-1] = hej[-1];} 81 82 /* 83 * Setup parameters necessary to read time from clock chip. 84 */ 85 clk_adrshift = 1; /* Addressed at long's... */ 86 clk_tweak = 2; /* ...and shift two */ 87 clk_page = (short *)vax_map_physmem(0x25400000, 1); 88 } 89 90 /* 91 * Why may we get memory errors during startup??? 92 */ 93 void 94 ka49_hardmem(void *arg) 95 { 96 if (cold == 0) 97 printf("Hard memory error\n"); 98 splhigh(); 99 } 100 101 void 102 ka49_softmem(void *arg) 103 { 104 if (cold == 0) 105 printf("Soft memory error\n"); 106 splhigh(); 107 } 108 109 /* 110 * KA49-specific IPRs. KA49 has the funny habit to control all caches 111 * via IPRs. 112 */ 113 #define PR_CCTL 0xa0 114 #define CCTL_ENABLE 0x00000001 115 #define CCTL_SSIZE 0x00000002 116 #define CCTL_VSIZE 0x00000004 117 #define CCTL_SW_ETM 0x40000000 118 #define CCTL_HW_ETM 0x80000000 119 120 #define PR_BCETSTS 0xa3 121 #define PR_BCEDSTS 0xa6 122 #define PR_NESTS 0xae 123 124 #define PR_VMAR 0xd0 125 #define PR_VTAG 0xd1 126 #define PR_ICSR 0xd3 127 #define ICSR_ENABLE 0x01 128 129 #define PR_PCCTL 0xf8 130 #define PCCTL_P_EN 0x10 131 #define PCCTL_I_EN 0x02 132 #define PCCTL_D_EN 0x01 133 134 void 135 ka49_cache_enable(void) 136 { 137 int start, slut; 138 139 /* 140 * Turn caches off. 141 */ 142 mtpr(0, PR_ICSR); 143 mtpr(0, PR_PCCTL); 144 mtpr(mfpr(PR_CCTL) | CCTL_SW_ETM, PR_CCTL); 145 146 /* 147 * Invalidate caches. 148 */ 149 mtpr(mfpr(PR_CCTL) | 0x10, PR_CCTL); /* Set cache size */ 150 mtpr(mfpr(PR_BCETSTS), PR_BCETSTS); /* Clear error bits */ 151 mtpr(mfpr(PR_BCEDSTS), PR_BCEDSTS); /* Clear error bits */ 152 mtpr(mfpr(PR_NESTS), PR_NESTS); /* Clear error bits */ 153 154 start = 0x01400000; 155 slut = 0x01440000; 156 157 /* Flush cache lines */ 158 for (; start < slut; start += 0x20) 159 mtpr(0, start); 160 161 mtpr((mfpr(PR_CCTL) & ~(CCTL_SW_ETM|CCTL_ENABLE)) | CCTL_HW_ETM, 162 PR_CCTL); 163 164 start = 0x01000000; 165 slut = 0x01040000; 166 167 /* clear tag and valid */ 168 for (; start < slut; start += 0x20) 169 mtpr(0, start); 170 171 mtpr(mfpr(PR_CCTL) | 0x10 | CCTL_ENABLE, PR_CCTL); /* enab. bcache */ 172 173 start = 0x01800000; 174 slut = 0x01802000; 175 176 /* Clear primary cache */ 177 for (; start < slut; start += 0x20) 178 mtpr(0, start); 179 180 /* Flush the pipes (via REI) */ 181 __asm("movpsl -(%sp); movab 1f,-(%sp); rei; 1:;"); 182 183 /* Enable primary cache */ 184 mtpr(PCCTL_P_EN|PCCTL_I_EN|PCCTL_D_EN, PR_PCCTL); 185 186 /* Enable the VIC */ 187 start = 0; 188 slut = 0x800; 189 for (; start < slut; start += 0x20) { 190 mtpr(start, PR_VMAR); 191 mtpr(0, PR_VTAG); 192 } 193 mtpr(ICSR_ENABLE, PR_ICSR); 194 } 195 196 void 197 ka49_memerr(void) 198 { 199 printf("Memory err!\n"); 200 } 201 202 int 203 ka49_mchk(void *addr) 204 { 205 panic("Machine check"); 206 return 0; 207 } 208 209 void 210 ka49_steal_pages(void) 211 { 212 /* 213 * Get the soft and hard memory error vectors now. 214 */ 215 scb_vecalloc(0x54, ka49_softmem, NULL, 0, NULL); 216 scb_vecalloc(0x60, ka49_hardmem, NULL, 0, NULL); 217 218 /* Turn on caches (to speed up execution a bit) */ 219 ka49_cache_enable(); 220 } 221 222 void 223 ka49_halt(void) 224 { 225 ((volatile uint8_t *) clk_page)[KA49_CPMBX] = KA49_HLT_HALT; 226 __asm("halt"); 227 } 228 229 void 230 ka49_reboot(int arg) 231 { 232 ((volatile uint8_t *) clk_page)[KA49_CPMBX] = KA49_HLT_BOOT; 233 __asm("halt"); 234 } 235