1 /* $NetBSD: machdep.c,v 1.9 2014/03/24 20:06:32 christos 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.9 2014/03/24 20:06:32 christos 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 cpu_setmodel("%s%s", id1, id2); 125 126 /* 127 * Set up the exception vectors and CPU-specific function 128 * vectors early on. We need the wbflush() vector set up 129 * before comcnattach() is called (or at least before the 130 * first printf() after that is called). 131 * Sets up mips_cpu_flags that may be queried by other 132 * functions called during startup. 133 * Also clears the I+D caches. 134 */ 135 mips_vector_init(NULL, false); 136 137 /* 138 * Calibrate timers. 139 */ 140 cal_timer(); 141 142 /* 143 * Set the VM page size. 144 */ 145 uvm_setpagesize(); 146 147 /* 148 * Look at arguments passed to us and compute boothowto. 149 */ 150 boothowto = RB_AUTOBOOT; 151 #ifdef KADB 152 boothowto |= RB_KDB; 153 #endif 154 155 /* 156 * Determine the memory size. 157 */ 158 memsize = *(volatile uint32_t *) 159 MIPS_PHYS_TO_KSEG1(RA_SYSCTL_BASE + RA_SYSCTL_CFG0); 160 memsize = __SHIFTOUT(memsize, SYSCTL_CFG0_DRAM_SIZE); 161 if (__predict_false(memsize == 0)) { 162 memsize = 2 << 20; 163 } else { 164 memsize = 4 << (20 + memsize); 165 } 166 167 physmem = btoc(memsize); 168 169 mem_clusters[mem_cluster_cnt].start = 0; 170 mem_clusters[mem_cluster_cnt].size = memsize; 171 mem_cluster_cnt++; 172 173 /* 174 * Load the memory into the VM system 175 */ 176 mips_page_physload((vaddr_t)kernel_text, kernend, 177 mem_clusters, mem_cluster_cnt, 178 NULL, 0); 179 180 /* 181 * Initialize message buffer (at end of core). 182 */ 183 mips_init_msgbuf(); 184 185 /* 186 * Initialize the virtual memory system. 187 */ 188 pmap_bootstrap(); 189 190 /* 191 * Init mapping for u page(s) for proc0. 192 */ 193 mips_init_lwp0_uarea(); 194 195 /* 196 * Initialize busses. 197 */ 198 ra_bus_init(); 199 200 #ifdef DDB 201 if (boothowto & RB_KDB) 202 Debugger(); 203 #endif 204 } 205 206 void 207 cpu_startup(void) 208 { 209 #ifdef DEBUG 210 extern int pmapdebug; 211 const int opmapdebug = pmapdebug; 212 pmapdebug = 0; /* Shut up pmap debug during bootstrap */ 213 #endif 214 215 cpu_startup_common(); 216 217 #ifdef DEBUG 218 pmapdebug = opmapdebug; 219 #endif 220 } 221 222 void 223 cpu_reboot(int howto, char *bootstr) 224 { 225 static int waittime = -1; 226 227 /* Take a snapshot before clobbering any registers. */ 228 savectx(lwp_getpcb(curlwp)); 229 230 /* If "always halt" was specified as a boot flag, obey. */ 231 if (boothowto & RB_HALT) 232 howto |= RB_HALT; 233 234 boothowto = howto; 235 236 /* If system is cold, just halt. */ 237 if (cold) { 238 boothowto |= RB_HALT; 239 goto haltsys; 240 } 241 242 if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 243 waittime = 0; 244 245 /* 246 * Synchronize the disks.... 247 */ 248 vfs_shutdown(); 249 250 /* 251 * If we've been adjusting the clock, the todr 252 * will be out of synch; adjust it now. 253 */ 254 resettodr(); 255 } 256 257 /* Disable interrupts. */ 258 splhigh(); 259 260 if (boothowto & RB_DUMP) 261 dumpsys(); 262 263 haltsys: 264 /* Run any shutdown hooks. */ 265 doshutdownhooks(); 266 267 pmf_system_shutdown(boothowto); 268 269 /* 270 * Firmware may autoboot (depending on settings), and we cannot pass 271 * flags to it (at least I haven't figured out how to yet), so 272 * we "pseudo-halt" now. 273 */ 274 if (boothowto & RB_HALT) { 275 printf("\n"); 276 printf("The operating system has halted.\n"); 277 printf("Please press any key to reboot.\n\n"); 278 cnpollc(1); /* For proper keyboard command handling */ 279 cngetc(); 280 cnpollc(0); 281 } 282 283 printf("reseting board...\n\n"); 284 mips_icache_sync_all(); 285 mips_dcache_wbinv_all(); 286 287 sysctl_write(RA_SYSCTL_RST, 1); /* SoC Reset */ 288 sysctl_write(RA_SYSCTL_RST, 0); 289 290 #if 0 291 __asm volatile("jr %0" :: "r"(MIPS_RESET_EXC_VEC)); 292 #endif 293 printf("Oops, back from reset\n\nSpinning..."); 294 for (;;) 295 /* spin forever */ ; /* XXX */ 296 /*NOTREACHED*/ 297 } 298 299 #define NO_SECURITY_MAGIC 0x27051958 300 #define SERIAL_MAGIC 0x100000 301 int 302 ra_check_memo_reg(int key) 303 { 304 uint32_t magic; 305 306 /* 307 * These registers may be overwritten. Keep the value around in case 308 * it is used later. Bitmask 1 == security, 2 = serial 309 */ 310 static int keyvalue; 311 312 switch (key) { 313 case NO_SECURITY: 314 magic = sysctl_read(RA_SYSCTL_MEMO0); 315 if ((NO_SECURITY_MAGIC == magic) || ((keyvalue & 1) != 0)) { 316 keyvalue |= 1; 317 return 1; 318 } 319 return 0; 320 break; 321 322 case SERIAL_CONSOLE: 323 magic = sysctl_read(RA_SYSCTL_MEMO1); 324 if (((SERIAL_MAGIC & magic) != 0) || ((keyvalue & 2) != 0)) { 325 keyvalue |= 2; 326 return 1; 327 } 328 return 0; 329 break; 330 331 default: 332 return 0; 333 } 334 335 } 336