1 /* $NetBSD: machdep.c,v 1.10 2014/04/30 01:01:47 matt Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 CradlePoint Technology, Inc. 5 * All rights reserved. 6 * 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 CRADLEPOINT TECHNOLOGY, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.10 2014/04/30 01:01:47 matt Exp $"); 32 33 #include <sys/param.h> 34 #include <sys/boot_flag.h> 35 #include <sys/buf.h> 36 #include <sys/cpu.h> 37 #include <sys/device.h> 38 #include <sys/mount.h> 39 #include <sys/kcore.h> 40 #include <sys/reboot.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/termios.h> 44 45 #include <uvm/uvm_extern.h> 46 47 #include <dev/cons.h> 48 49 #include <mips/cache.h> 50 #include <mips/locore.h> 51 #include <mips/cpuregs.h> 52 53 #include <mips/ralink/ralink_reg.h> 54 #include <mips/ralink/ralink_var.h> 55 56 /* structures we define/alloc for other files in the kernel */ 57 struct vm_map *phys_map = NULL; 58 59 int mem_cluster_cnt = 0; 60 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 61 62 void mach_init(void); 63 64 static inline uint32_t 65 sysctl_read(u_int offset) 66 { 67 return *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset); 68 } 69 70 static inline void 71 sysctl_write(u_int offset, uint32_t val) 72 { 73 *RA_IOREG_VADDR(RA_SYSCTL_BASE, offset) = val; 74 } 75 76 static void 77 cal_timer(void) 78 { 79 uint32_t cntfreq; 80 81 cntfreq = curcpu()->ci_cpu_freq = RA_CLOCK_RATE; 82 83 /* MIPS 4Kc CP0 counts every other clock */ 84 if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 85 cntfreq /= 2; 86 87 curcpu()->ci_cycles_per_hz = (cntfreq + hz / 2) / hz; 88 89 /* Compute number of cycles per 1us (1/MHz). 0.5MHz is for roundup. */ 90 curcpu()->ci_divisor_delay = ((cntfreq + 500000) / 1000000); 91 } 92 93 void 94 mach_init(void) 95 { 96 vaddr_t kernend; 97 psize_t memsize; 98 99 extern char kernel_text[]; 100 extern char edata[], end[]; /* From Linker */ 101 102 /* clear the BSS segment */ 103 kernend = mips_round_page(end); 104 105 memset(edata, 0, kernend - (vaddr_t)edata); 106 107 #ifdef RALINK_CONSOLE_EARLY 108 /* 109 * set up early console 110 * cannot printf until sometime (?) in mips_vector_init 111 * meanwhile can use the ra_console_putc primitive if necessary 112 */ 113 ralink_console_early(); 114 #endif 115 116 /* set CPU model info for sysctl_hw */ 117 uint32_t tmp1, tmp2; 118 char id1[5], id2[5]; 119 tmp1 = sysctl_read(RA_SYSCTL_ID0); 120 memcpy(id1, &tmp1, sizeof(tmp1)); 121 tmp2 = sysctl_read(RA_SYSCTL_ID1); 122 memcpy(id2, &tmp2, sizeof(tmp2)); 123 id2[4] = id1[4] = '\0'; 124 if (id2[2] == ' ') { 125 id2[2] = '\0'; 126 } else if (id2[3] == ' ') { 127 id2[3] = '\0'; 128 } else { 129 id2[4] = '\0'; 130 } 131 cpu_setmodel("%s%s", id1, id2); 132 133 /* 134 * Set up the exception vectors and CPU-specific function 135 * vectors early on. We need the wbflush() vector set up 136 * before comcnattach() is called (or at least before the 137 * first printf() after that is called). 138 * Sets up mips_cpu_flags that may be queried by other 139 * functions called during startup. 140 * Also clears the I+D caches. 141 */ 142 mips_vector_init(NULL, false); 143 144 /* 145 * Calibrate timers. 146 */ 147 cal_timer(); 148 149 /* 150 * Set the VM page size. 151 */ 152 uvm_setpagesize(); 153 154 /* 155 * Look at arguments passed to us and compute boothowto. 156 */ 157 boothowto = RB_AUTOBOOT; 158 #ifdef KADB 159 boothowto |= RB_KDB; 160 #endif 161 162 /* 163 * Determine the memory size. 164 */ 165 #if defined(MT7620) 166 memsize = 128 << 20; 167 #else 168 memsize = *(volatile uint32_t *) 169 MIPS_PHYS_TO_KSEG1(RA_SYSCTL_BASE + RA_SYSCTL_CFG0); 170 memsize = __SHIFTOUT(memsize, SYSCTL_CFG0_DRAM_SIZE); 171 if (__predict_false(memsize == 0)) { 172 memsize = 2 << 20; 173 } else { 174 memsize = 4 << (20 + memsize); 175 } 176 #endif 177 178 physmem = btoc(memsize); 179 180 mem_clusters[mem_cluster_cnt].start = 0; 181 mem_clusters[mem_cluster_cnt].size = memsize; 182 mem_cluster_cnt++; 183 184 /* 185 * Load the memory into the VM system 186 */ 187 mips_page_physload((vaddr_t)kernel_text, kernend, 188 mem_clusters, mem_cluster_cnt, 189 NULL, 0); 190 191 /* 192 * Initialize message buffer (at end of core). 193 */ 194 mips_init_msgbuf(); 195 196 /* 197 * Initialize the virtual memory system. 198 */ 199 pmap_bootstrap(); 200 201 /* 202 * Init mapping for u page(s) for proc0. 203 */ 204 mips_init_lwp0_uarea(); 205 206 /* 207 * Initialize busses. 208 */ 209 ra_bus_init(); 210 211 #ifdef DDB 212 if (boothowto & RB_KDB) 213 Debugger(); 214 #endif 215 } 216 217 void 218 cpu_startup(void) 219 { 220 #ifdef DEBUG 221 extern int pmapdebug; 222 const int opmapdebug = pmapdebug; 223 pmapdebug = 0; /* Shut up pmap debug during bootstrap */ 224 #endif 225 226 cpu_startup_common(); 227 228 #ifdef DEBUG 229 pmapdebug = opmapdebug; 230 #endif 231 } 232 233 void 234 cpu_reboot(int howto, char *bootstr) 235 { 236 static int waittime = -1; 237 238 /* Take a snapshot before clobbering any registers. */ 239 savectx(lwp_getpcb(curlwp)); 240 241 /* If "always halt" was specified as a boot flag, obey. */ 242 if (boothowto & RB_HALT) 243 howto |= RB_HALT; 244 245 boothowto = howto; 246 247 /* If system is cold, just halt. */ 248 if (cold) { 249 boothowto |= RB_HALT; 250 goto haltsys; 251 } 252 253 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 254 waittime = 0; 255 256 /* 257 * Synchronize the disks.... 258 */ 259 vfs_shutdown(); 260 261 /* 262 * If we've been adjusting the clock, the todr 263 * will be out of synch; adjust it now. 264 */ 265 resettodr(); 266 } 267 268 /* Disable interrupts. */ 269 splhigh(); 270 271 if (boothowto & RB_DUMP) 272 dumpsys(); 273 274 haltsys: 275 /* Run any shutdown hooks. */ 276 doshutdownhooks(); 277 278 pmf_system_shutdown(boothowto); 279 280 /* 281 * Firmware may autoboot (depending on settings), and we cannot pass 282 * flags to it (at least I haven't figured out how to yet), so 283 * we "pseudo-halt" now. 284 */ 285 if (boothowto & RB_HALT) { 286 printf("\n"); 287 printf("The operating system has halted.\n"); 288 printf("Please press any key to reboot.\n\n"); 289 cnpollc(1); /* For proper keyboard command handling */ 290 cngetc(); 291 cnpollc(0); 292 } 293 294 printf("reseting board...\n\n"); 295 mips_icache_sync_all(); 296 mips_dcache_wbinv_all(); 297 298 sysctl_write(RA_SYSCTL_RST, 1); /* SoC Reset */ 299 sysctl_write(RA_SYSCTL_RST, 0); 300 301 #if 0 302 __asm volatile("jr %0" :: "r"(MIPS_RESET_EXC_VEC)); 303 #endif 304 printf("Oops, back from reset\n\nSpinning..."); 305 for (;;) 306 /* spin forever */ ; /* XXX */ 307 /*NOTREACHED*/ 308 } 309 310 #define NO_SECURITY_MAGIC 0x27051958 311 #define SERIAL_MAGIC 0x100000 312 int 313 ra_check_memo_reg(int key) 314 { 315 uint32_t magic; 316 317 /* 318 * These registers may be overwritten. Keep the value around in case 319 * it is used later. Bitmask 1 == security, 2 = serial 320 */ 321 static int keyvalue; 322 323 switch (key) { 324 case NO_SECURITY: 325 magic = sysctl_read(RA_SYSCTL_MEMO0); 326 if ((NO_SECURITY_MAGIC == magic) || ((keyvalue & 1) != 0)) { 327 keyvalue |= 1; 328 return 1; 329 } 330 return 0; 331 break; 332 333 case SERIAL_CONSOLE: 334 magic = sysctl_read(RA_SYSCTL_MEMO1); 335 if (magic == 0 336 || (SERIAL_MAGIC & magic) != 0 337 || (keyvalue & 2) != 0) { 338 keyvalue |= 2; 339 return 1; 340 } 341 return 0; 342 break; 343 344 default: 345 return 0; 346 } 347 348 } 349