1 1.27 thorpej /* $NetBSD: machdep.c,v 1.27 2024/03/05 14:15:30 thorpej Exp $ */ 2 1.1 dyoung 3 1.1 dyoung /*- 4 1.1 dyoung * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko. 5 1.1 dyoung * All rights reserved. 6 1.1 dyoung * 7 1.1 dyoung * Redistribution and use in source and binary forms, with or 8 1.1 dyoung * without modification, are permitted provided that the following 9 1.1 dyoung * conditions are met: 10 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 11 1.1 dyoung * notice, this list of conditions and the following disclaimer. 12 1.1 dyoung * 2. Redistributions in binary form must reproduce the above 13 1.1 dyoung * copyright notice, this list of conditions and the following 14 1.1 dyoung * disclaimer in the documentation and/or other materials provided 15 1.1 dyoung * with the distribution. 16 1.1 dyoung * 3. The names of the authors may not be used to endorse or promote 17 1.1 dyoung * products derived from this software without specific prior 18 1.1 dyoung * written permission. 19 1.1 dyoung * 20 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY 21 1.1 dyoung * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 1.1 dyoung * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 1.1 dyoung * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 24 1.1 dyoung * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 1.1 dyoung * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 1.1 dyoung * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 1.1 dyoung * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 dyoung * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 29 1.1 dyoung * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 1.1 dyoung * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 1.1 dyoung * OF SUCH DAMAGE. 32 1.1 dyoung */ 33 1.19 rmind 34 1.1 dyoung /* 35 1.19 rmind * Copyright (c) 1988 University of Utah. 36 1.1 dyoung * Copyright (c) 1992, 1993 37 1.1 dyoung * The Regents of the University of California. All rights reserved. 38 1.1 dyoung * 39 1.1 dyoung * This code is derived from software contributed to Berkeley by 40 1.1 dyoung * the Systems Programming Group of the University of Utah Computer 41 1.1 dyoung * Science Department, The Mach Operating System project at 42 1.1 dyoung * Carnegie-Mellon University and Ralph Campbell. 43 1.1 dyoung * 44 1.1 dyoung * Redistribution and use in source and binary forms, with or without 45 1.1 dyoung * modification, are permitted provided that the following conditions 46 1.1 dyoung * are met: 47 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 48 1.1 dyoung * notice, this list of conditions and the following disclaimer. 49 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright 50 1.1 dyoung * notice, this list of conditions and the following disclaimer in the 51 1.1 dyoung * documentation and/or other materials provided with the distribution. 52 1.1 dyoung * 3. Neither the name of the University nor the names of its contributors 53 1.1 dyoung * may be used to endorse or promote products derived from this software 54 1.1 dyoung * without specific prior written permission. 55 1.1 dyoung * 56 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 1.1 dyoung * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 1.1 dyoung * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 1.1 dyoung * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 1.1 dyoung * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 1.1 dyoung * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 1.1 dyoung * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 1.1 dyoung * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 1.1 dyoung * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 1.1 dyoung * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 1.1 dyoung * SUCH DAMAGE. 67 1.1 dyoung * 68 1.1 dyoung * @(#)machdep.c 8.3 (Berkeley) 1/12/94 69 1.1 dyoung * from: Utah Hdr: machdep.c 1.63 91/04/24 70 1.1 dyoung */ 71 1.1 dyoung 72 1.19 rmind #include <sys/cdefs.h> 73 1.27 thorpej __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.27 2024/03/05 14:15:30 thorpej Exp $"); 74 1.1 dyoung 75 1.1 dyoung #include "opt_ddb.h" 76 1.1 dyoung #include "opt_kgdb.h" 77 1.1 dyoung 78 1.1 dyoung #include "opt_memsize.h" 79 1.10 apb #include "opt_modular.h" 80 1.1 dyoung #include "opt_ethaddr.h" 81 1.1 dyoung 82 1.1 dyoung #include "opt_pci.h" 83 1.1 dyoung #include "pci.h" 84 1.1 dyoung 85 1.1 dyoung #include <sys/param.h> 86 1.21 matt #include <sys/boot_flag.h> 87 1.21 matt #include <sys/buf.h> 88 1.21 matt #include <sys/device.h> 89 1.21 matt #include <sys/kcore.h> 90 1.1 dyoung #include <sys/kernel.h> 91 1.21 matt #include <sys/ksyms.h> 92 1.21 matt #include <sys/mount.h> 93 1.1 dyoung #include <sys/reboot.h> 94 1.21 matt #include <sys/systm.h> 95 1.1 dyoung #include <sys/termios.h> 96 1.23 christos #include <sys/cpu.h> 97 1.1 dyoung 98 1.1 dyoung #include <net/if.h> 99 1.1 dyoung #include <net/if_ether.h> 100 1.1 dyoung 101 1.1 dyoung #include <uvm/uvm_extern.h> 102 1.1 dyoung 103 1.1 dyoung #include <dev/cons.h> 104 1.1 dyoung 105 1.1 dyoung #include "ksyms.h" 106 1.1 dyoung 107 1.8 ad #if NKSYMS || defined(DDB) || defined(MODULAR) 108 1.21 matt #include <mips/db_machdep.h> 109 1.1 dyoung #include <ddb/db_extern.h> 110 1.1 dyoung #endif 111 1.1 dyoung 112 1.1 dyoung #include <mips/cache.h> 113 1.1 dyoung #include <mips/locore.h> 114 1.1 dyoung 115 1.1 dyoung #include <mips/adm5120/include/adm5120reg.h> 116 1.1 dyoung #include <mips/adm5120/include/adm5120var.h> 117 1.1 dyoung #include <mips/adm5120/include/adm5120_extiovar.h> 118 1.1 dyoung #include <mips/adm5120/include/adm5120_obiovar.h> 119 1.1 dyoung #include <mips/adm5120/include/adm5120_mainbusvar.h> 120 1.1 dyoung #include <mips/adm5120/include/adm5120_pcivar.h> 121 1.1 dyoung #include <mips/adm5120/dev/uart.h> 122 1.1 dyoung 123 1.1 dyoung #ifndef MEMSIZE 124 1.1 dyoung #define MEMSIZE 4 * 1024 * 1024 125 1.1 dyoung #endif /* !MEMSIZE */ 126 1.1 dyoung 127 1.1 dyoung /* Maps for VM objects. */ 128 1.1 dyoung struct vm_map *phys_map = NULL; 129 1.1 dyoung 130 1.1 dyoung int maxmem; /* max memory per process */ 131 1.1 dyoung 132 1.1 dyoung int mem_cluster_cnt; 133 1.1 dyoung phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 134 1.1 dyoung 135 1.1 dyoung struct adm5120_config adm5120_configuration; 136 1.1 dyoung 137 1.1 dyoung void adm5120_setcpufreq(void); 138 1.1 dyoung 139 1.1 dyoung void 140 1.1 dyoung adm5120_setcpufreq(void) 141 1.1 dyoung { 142 1.1 dyoung uint32_t v, freq; 143 1.1 dyoung 144 1.1 dyoung v = SW_READ(SW_CODE_REG); 145 1.1 dyoung switch (v & CLKS_MASK) { 146 1.1 dyoung case CLKS_175MHZ: 147 1.1 dyoung freq = 175 * 1000 * 1000; 148 1.1 dyoung break; 149 1.1 dyoung case CLKS_200MHZ: 150 1.1 dyoung freq = 200 * 1000 * 1000; 151 1.1 dyoung break; 152 1.1 dyoung default: 153 1.1 dyoung panic("adm5120: cannot determine CPU clock speed"); 154 1.1 dyoung } 155 1.1 dyoung 156 1.1 dyoung curcpu()->ci_cpu_freq = freq; 157 1.1 dyoung curcpu()->ci_cycles_per_hz = (freq + hz / 2) / hz / 2; 158 1.1 dyoung curcpu()->ci_divisor_delay = ((freq + 500000) / 1000000) / 2; 159 1.1 dyoung } 160 1.1 dyoung 161 1.1 dyoung void mach_init(int, char **, void *, void *); /* XXX */ 162 1.1 dyoung 163 1.1 dyoung static void 164 1.1 dyoung copy_args(int argc, char **argv) 165 1.1 dyoung { 166 1.1 dyoung struct adm5120_config *admc = &adm5120_configuration; 167 1.1 dyoung int i; 168 1.1 dyoung char *buf; 169 1.1 dyoung size_t buflen, rc; 170 1.1 dyoung 171 1.1 dyoung buf = admc->args; 172 1.1 dyoung buflen = sizeof(admc->args); 173 1.1 dyoung 174 1.1 dyoung if (argc >= __arraycount(admc->argv)) 175 1.1 dyoung panic("%s: too many boot args\n", __func__); 176 1.1 dyoung 177 1.1 dyoung for (i = 0; buflen > 0 && i < argc && argv[i] != NULL; i++) { 178 1.1 dyoung admc->argv[i] = buf; 179 1.1 dyoung if ((rc = strlcpy(buf, argv[i], buflen)) >= buflen) 180 1.1 dyoung panic("%s: boot args too long\n", __func__); 181 1.1 dyoung 182 1.1 dyoung buf += rc; 183 1.1 dyoung buflen -= rc; 184 1.1 dyoung *buf++ = '\0'; 185 1.1 dyoung buflen--; 186 1.1 dyoung } 187 1.1 dyoung if (i < argc) 188 1.1 dyoung panic("%s: boot args too long\n", __func__); 189 1.1 dyoung 190 1.1 dyoung admc->argc = argc; 191 1.1 dyoung } 192 1.1 dyoung 193 1.1 dyoung static void 194 1.1 dyoung parse_args(prop_dictionary_t properties, int argc, char **argv, 195 1.1 dyoung uint32_t *memsizep) 196 1.1 dyoung { 197 1.1 dyoung char buf[32]; 198 1.1 dyoung char *key, *val, *valend; 199 1.1 dyoung unsigned long tmp; 200 1.1 dyoung int i; 201 1.1 dyoung uint8_t enaddr[ETHER_ADDR_LEN]; 202 1.1 dyoung 203 1.1 dyoung if (memsizep != NULL) 204 1.1 dyoung *memsizep = MEMSIZE; 205 1.1 dyoung 206 1.1 dyoung for (i = 0; i < argc && argv[i] != NULL; i++) { 207 1.1 dyoung if (strlcpy(buf, argv[i], sizeof(buf)) >= sizeof(buf)) 208 1.1 dyoung goto err; 209 1.1 dyoung val = buf; 210 1.1 dyoung key = strsep(&val, "="); 211 1.1 dyoung if (val == NULL) 212 1.1 dyoung goto err; 213 1.1 dyoung if (strcmp(key, "mem") == 0) { 214 1.1 dyoung tmp = strtoul(val, &valend, 10); 215 1.1 dyoung if (val == valend || *valend != 'M') 216 1.1 dyoung goto err; 217 1.1 dyoung if (memsizep != NULL) 218 1.1 dyoung *memsizep = tmp * 1024 * 1024; 219 1.1 dyoung } else if (strcmp(key, "HZ") == 0) 220 1.1 dyoung ; 221 1.1 dyoung else if (strcmp(key, "gpio") == 0) { 222 1.1 dyoung prop_number_t pn; 223 1.1 dyoung 224 1.1 dyoung tmp = strtoul(val, &valend, 10); 225 1.1 dyoung if (val == valend || *valend != '\0') 226 1.1 dyoung goto err; 227 1.1 dyoung if (properties == NULL) 228 1.1 dyoung continue; 229 1.1 dyoung pn = prop_number_create_unsigned_integer(tmp); 230 1.1 dyoung if (pn == NULL) { 231 1.1 dyoung printf( 232 1.1 dyoung "%s: prop_number_create_unsigned_integer\n", 233 1.1 dyoung __func__); 234 1.1 dyoung continue; 235 1.1 dyoung } 236 1.1 dyoung if (!prop_dictionary_set(properties, "initial-gpio", 237 1.1 dyoung pn)) { 238 1.1 dyoung printf("%s: prop_dictionary_set(gpio)\n", 239 1.1 dyoung __func__); 240 1.1 dyoung } 241 1.1 dyoung prop_object_release(pn); 242 1.1 dyoung } else if (strcmp(key, "kmac") == 0) { 243 1.1 dyoung prop_data_t pd; 244 1.1 dyoung 245 1.17 christos (void)ether_aton_r(enaddr, sizeof(enaddr), val); 246 1.1 dyoung if (properties == NULL) 247 1.1 dyoung continue; 248 1.1 dyoung pd = prop_data_create_data(enaddr, sizeof(enaddr)); 249 1.1 dyoung if (pd == NULL) { 250 1.1 dyoung printf("%s: prop_data_create_data\n", __func__); 251 1.1 dyoung continue; 252 1.1 dyoung } 253 1.15 martin if (!prop_dictionary_set(properties, "mac-address", pd)) { 254 1.1 dyoung printf("%s: prop_dictionary_set(mac)\n", 255 1.1 dyoung __func__); 256 1.1 dyoung } 257 1.1 dyoung prop_object_release(pd); 258 1.1 dyoung } else if (strcmp(key, "board") == 0) 259 1.1 dyoung printf("Routerboard %s\n", val); 260 1.1 dyoung else if (strcmp(key, "boot") == 0) 261 1.1 dyoung ; 262 1.1 dyoung continue; 263 1.1 dyoung err: 264 1.1 dyoung printf("bad argv[%d] (%s)\n", i, argv[i]); 265 1.1 dyoung } 266 1.1 dyoung } 267 1.1 dyoung 268 1.1 dyoung void 269 1.1 dyoung mach_init(int argc, char **argv, void *a2, void *a3) 270 1.1 dyoung { 271 1.1 dyoung struct adm5120_config *admc = &adm5120_configuration; 272 1.1 dyoung uint32_t memsize; 273 1.1 dyoung vaddr_t kernend; 274 1.1 dyoung 275 1.1 dyoung extern char edata[], end[]; /* XXX */ 276 1.1 dyoung 277 1.1 dyoung /* clear the BSS segment */ 278 1.1 dyoung kernend = mips_round_page(end); 279 1.1 dyoung memset(edata, 0, kernend - (vaddr_t)edata); 280 1.1 dyoung 281 1.1 dyoung /* set CPU model info for sysctl_hw */ 282 1.23 christos cpu_setmodel("Infineon ADM5120"); 283 1.1 dyoung 284 1.1 dyoung /* 285 1.1 dyoung * Set up the exception vectors and CPU-specific function 286 1.1 dyoung * vectors early on. We need the wbflush() vector set up 287 1.1 dyoung * before comcnattach() is called (or at least before the 288 1.1 dyoung * first printf() after that is called). 289 1.1 dyoung * Sets up mips_cpu_flags that may be queried by other 290 1.1 dyoung * functions called during startup. 291 1.1 dyoung * Also clears the I+D caches. 292 1.1 dyoung */ 293 1.20 matt mips_vector_init(NULL, false); 294 1.1 dyoung 295 1.25 cherry uvm_md_init(); 296 1.1 dyoung 297 1.1 dyoung adm5120_setcpufreq(); 298 1.1 dyoung 299 1.1 dyoung /* 300 1.1 dyoung * Initialize bus space tags. 301 1.1 dyoung */ 302 1.1 dyoung obio_bus_mem_init(&admc->obio_space, admc); 303 1.1 dyoung extio_bus_mem_init(&admc->extio_space, admc); 304 1.1 dyoung #if NPCI > 0 305 1.1 dyoung pciio_bus_mem_init(&admc->pciio_space, admc); 306 1.1 dyoung pcimem_bus_mem_init(&admc->pcimem_space, admc); 307 1.1 dyoung #endif 308 1.1 dyoung 309 1.1 dyoung /* 310 1.1 dyoung * Initialize bus DMA tag. 311 1.1 dyoung */ 312 1.1 dyoung obio_dma_init(&admc->obio_dmat); 313 1.1 dyoung 314 1.1 dyoung /* 315 1.1 dyoung * Attach serial console. 316 1.1 dyoung */ 317 1.1 dyoung uart_cnattach(); 318 1.1 dyoung 319 1.1 dyoung /* 320 1.1 dyoung * Look at arguments passed to us and compute boothowto. 321 1.1 dyoung */ 322 1.1 dyoung boothowto = RB_AUTOBOOT; 323 1.1 dyoung #ifdef KADB 324 1.1 dyoung boothowto |= RB_KDB; 325 1.1 dyoung #endif 326 1.1 dyoung 327 1.1 dyoung parse_args(NULL, argc, argv, &memsize); 328 1.1 dyoung 329 1.1 dyoung /* 330 1.1 dyoung * Determine the memory size. 331 1.1 dyoung * 332 1.1 dyoung * Note: Reserve the first page! That's where the trap 333 1.1 dyoung * vectors are located. 334 1.1 dyoung */ 335 1.1 dyoung 336 1.1 dyoung #if 0 337 1.1 dyoung if (GET_MEMSIZE(memsize) == 0) { 338 1.1 dyoung uint32_t val; 339 1.1 dyoung 340 1.1 dyoung /* This does not seem to work... --dyoung */ 341 1.1 dyoung val = SW_READ(SW_MEMCONT_REG); 342 1.1 dyoung printf("SW_MEMCONT_REG: 0x%08" PRIx32 "\n", val); 343 1.1 dyoung switch (val & SDRAM_SIZE_MASK) { 344 1.1 dyoung case SDRAM_SIZE_4MBYTES: 345 1.1 dyoung memsize = 4 * 1024 * 1024; 346 1.1 dyoung break; 347 1.1 dyoung case SDRAM_SIZE_8MBYTES: 348 1.1 dyoung memsize = 8 * 1024 * 1024; 349 1.1 dyoung break; 350 1.1 dyoung case SDRAM_SIZE_16MBYTES: 351 1.1 dyoung memsize = 16 * 1024 * 1024; 352 1.1 dyoung break; 353 1.1 dyoung case SDRAM_SIZE_64MBYTES: 354 1.1 dyoung memsize = 64 * 1024 * 1024; 355 1.1 dyoung break; 356 1.1 dyoung case SDRAM_SIZE_128MBYTES: 357 1.1 dyoung memsize = 128 * 1024 * 1024; 358 1.1 dyoung break; 359 1.1 dyoung default: 360 1.1 dyoung panic("adm5120: cannot determine memory size"); 361 1.1 dyoung } 362 1.1 dyoung } 363 1.1 dyoung #endif 364 1.1 dyoung 365 1.1 dyoung physmem = btoc(memsize); 366 1.1 dyoung 367 1.1 dyoung mem_clusters[mem_cluster_cnt].start = PAGE_SIZE; 368 1.1 dyoung mem_clusters[mem_cluster_cnt].size = 369 1.1 dyoung memsize - mem_clusters[mem_cluster_cnt].start; 370 1.1 dyoung mem_cluster_cnt++; 371 1.1 dyoung 372 1.1 dyoung /* 373 1.1 dyoung * Load the rest of the available pages into the VM system. 374 1.1 dyoung */ 375 1.20 matt mips_page_physload(MIPS_KSEG0_START, (vaddr_t) kernend, 376 1.20 matt mem_clusters, mem_cluster_cnt, NULL, 0); 377 1.1 dyoung 378 1.1 dyoung /* 379 1.1 dyoung * Initialize message buffer (at end of core). 380 1.1 dyoung */ 381 1.1 dyoung mips_init_msgbuf(); 382 1.1 dyoung 383 1.1 dyoung /* 384 1.1 dyoung * Initialize the virtual memory system. 385 1.1 dyoung */ 386 1.1 dyoung pmap_bootstrap(); 387 1.1 dyoung 388 1.1 dyoung /* 389 1.13 rmind * Allocate uarea page for lwp0 and set it. 390 1.1 dyoung */ 391 1.14 matt mips_init_lwp0_uarea(); 392 1.1 dyoung 393 1.1 dyoung /* 394 1.1 dyoung * Initialize debuggers, and break into them, if appropriate. 395 1.1 dyoung */ 396 1.1 dyoung #ifdef DDB 397 1.1 dyoung if (boothowto & RB_KDB) 398 1.1 dyoung Debugger(); 399 1.1 dyoung #endif 400 1.1 dyoung 401 1.1 dyoung copy_args(argc, argv); 402 1.1 dyoung } 403 1.1 dyoung 404 1.1 dyoung void 405 1.1 dyoung consinit(void) 406 1.1 dyoung { 407 1.1 dyoung 408 1.1 dyoung /* 409 1.1 dyoung * Everything related to console initialization is done 410 1.1 dyoung * in mach_init(). 411 1.1 dyoung */ 412 1.1 dyoung } 413 1.1 dyoung 414 1.1 dyoung void 415 1.1 dyoung cpu_startup(void) 416 1.1 dyoung { 417 1.1 dyoung struct adm5120_config *admc = &adm5120_configuration; 418 1.1 dyoung 419 1.1 dyoung if ((admc->properties = prop_dictionary_create()) == NULL) 420 1.1 dyoung printf("%s: prop_dictionary_create\n", __func__); 421 1.1 dyoung parse_args(admc->properties, admc->argc, admc->argv, NULL); 422 1.1 dyoung 423 1.24 matt cpu_startup_common(); 424 1.1 dyoung } 425 1.1 dyoung 426 1.1 dyoung void 427 1.1 dyoung cpu_reboot(int howto, char *bootstr) 428 1.1 dyoung { 429 1.1 dyoung static int waittime = -1; 430 1.1 dyoung 431 1.1 dyoung /* Take a snapshot before clobbering any registers. */ 432 1.20 matt savectx(curpcb); 433 1.1 dyoung 434 1.1 dyoung /* If "always halt" was specified as a boot flag, obey. */ 435 1.1 dyoung if (boothowto & RB_HALT) 436 1.1 dyoung howto |= RB_HALT; 437 1.1 dyoung 438 1.1 dyoung boothowto = howto; 439 1.1 dyoung 440 1.1 dyoung /* If system is cold, just halt. */ 441 1.1 dyoung if (cold) { 442 1.1 dyoung boothowto |= RB_HALT; 443 1.1 dyoung goto haltsys; 444 1.1 dyoung } 445 1.1 dyoung 446 1.1 dyoung if ((boothowto & RB_NOSYNC) == 0 && waittime < 0) { 447 1.1 dyoung waittime = 0; 448 1.1 dyoung 449 1.1 dyoung /* 450 1.1 dyoung * Synchronize the disks.... 451 1.1 dyoung */ 452 1.1 dyoung vfs_shutdown(); 453 1.1 dyoung } 454 1.1 dyoung 455 1.1 dyoung /* Disable interrupts. */ 456 1.1 dyoung splhigh(); 457 1.1 dyoung 458 1.1 dyoung if (boothowto & RB_DUMP) 459 1.1 dyoung dumpsys(); 460 1.1 dyoung 461 1.1 dyoung haltsys: 462 1.1 dyoung /* Run any shutdown hooks. */ 463 1.1 dyoung doshutdownhooks(); 464 1.1 dyoung 465 1.7 dyoung pmf_system_shutdown(boothowto); 466 1.7 dyoung 467 1.1 dyoung /* 468 1.1 dyoung * Routerboard BIOS may autoboot, so "pseudo-halt". 469 1.1 dyoung */ 470 1.1 dyoung if (boothowto & RB_HALT) { 471 1.1 dyoung printf("\n"); 472 1.1 dyoung printf("The operating system has halted.\n"); 473 1.1 dyoung printf("Please press any key to reboot.\n\n"); 474 1.1 dyoung cnpollc(1); /* For proper keyboard command handling */ 475 1.1 dyoung cngetc(); 476 1.1 dyoung cnpollc(0); 477 1.1 dyoung } 478 1.1 dyoung 479 1.26 msaitoh printf("resetting board...\n\n"); 480 1.1 dyoung mips_icache_sync_all(); 481 1.1 dyoung mips_dcache_wbinv_all(); 482 1.1 dyoung SW_WRITE(SW_SFTRES_REG, 0); /* reset */ 483 1.1 dyoung for (;;) 484 1.1 dyoung /* spin forever */ ; /* XXX */ 485 1.1 dyoung /*NOTREACHED*/ 486 1.1 dyoung } 487