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