1 /* $NetBSD: machdep.c,v 1.7 2016/12/22 14:47:57 cherry Exp $ */ 2 3 /* 4 * Copyright 2001, 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Copyright (c) 1988 University of Utah. 40 * Copyright (c) 1992, 1993 41 * The Regents of the University of California. All rights reserved. 42 * 43 * This code is derived from software contributed to Berkeley by 44 * the Systems Programming Group of the University of Utah Computer 45 * Science Department, The Mach Operating System project at 46 * Carnegie-Mellon University and Ralph Campbell. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. Neither the name of the University nor the names of its contributors 57 * may be used to endorse or promote products derived from this software 58 * without specific prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 61 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 62 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 63 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 64 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 65 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 66 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 * @(#)machdep.c 8.3 (Berkeley) 1/12/94 73 * from: Utah Hdr: machdep.c 1.63 91/04/24 74 */ 75 76 /* 77 * Copyright (c) 2009, 2010 Miodrag Vallat. 78 * 79 * Permission to use, copy, modify, and distribute this software for any 80 * purpose with or without fee is hereby granted, provided that the above 81 * copyright notice and this permission notice appear in all copies. 82 * 83 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 84 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 85 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 86 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 87 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 88 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 89 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 90 */ 91 92 #include <sys/cdefs.h> 93 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.7 2016/12/22 14:47:57 cherry Exp $"); 94 95 #include "opt_ddb.h" 96 #include "opt_execfmt.h" 97 #include "opt_modular.h" 98 99 #define _MIPS_BUS_DMA_PRIVATE 100 101 #include <sys/param.h> 102 #include <sys/systm.h> 103 #include <sys/kernel.h> 104 #include <sys/buf.h> 105 #include <sys/reboot.h> 106 #include <sys/mount.h> 107 #include <sys/kcore.h> 108 #include <sys/boot_flag.h> 109 #include <sys/termios.h> 110 #include <sys/ksyms.h> 111 #include <sys/device.h> 112 #include <sys/cpu.h> 113 114 #include <uvm/uvm_extern.h> 115 116 #include <dev/cons.h> 117 118 #include "ksyms.h" 119 120 #if NKSYMS || defined(DDB) || defined(MODULAR) 121 #include <machine/db_machdep.h> 122 #include <ddb/db_extern.h> 123 #include <sys/exec_elf.h> 124 #endif 125 126 #include <evbmips/loongson/autoconf.h> 127 #include <evbmips/loongson/loongson_intr.h> 128 #include <evbmips/loongson/loongson_bus_defs.h> 129 #include <machine/cpu.h> 130 #include <machine/psl.h> 131 132 #include <mips/locore.h> 133 134 #include <mips/bonito/bonitoreg.h> 135 #include <mips/bonito/bonitovar.h> 136 #include <mips/pmon/pmon.h> 137 138 #include "sisfb.h" 139 #if NSISFB > 0 140 #include <dev/pci/sisfb.h> 141 #endif 142 143 #include "lynxfb.h" 144 #if NLYNXFB > 0 145 #include <dev/pci/lynxfbvar.h> 146 #endif 147 148 #include "pckbc.h" 149 #if NPCKBC > 0 150 #include <dev/isa/isareg.h> 151 #include <dev/ic/i8042reg.h> 152 #include <dev/ic/pckbcvar.h> 153 #endif 154 #include "pckbd.h" 155 #include "ukbd.h" 156 #if NUKBD > 0 157 #include <dev/usb/ukbdvar.h> 158 #endif 159 #if NPCKBD > 0 || NUKBD > 0 160 #include <dev/wscons/wskbdvar.h> 161 #endif 162 163 #include "com.h" 164 #if NCOM > 0 165 #include <dev/ic/comreg.h> 166 #include <dev/ic/comvar.h> 167 168 bus_space_tag_t comconsiot; 169 bus_addr_t comconsaddr; 170 int comconsrate = 0; 171 #endif /* NCOM > 0 */ 172 173 #ifdef LOW_DEBUG 174 #define DPRINTF(x) printf x 175 #define DPPRINTF(x) pmon_printf x 176 #else 177 #define DPRINTF(x) 178 #define DPPRINTF(x) 179 #endif 180 181 182 int ex_mallocsafe = 0; 183 struct extent *loongson_io_ex = NULL; 184 struct extent *loongson_mem_ex = NULL; 185 struct mips_bus_space bonito_iot; 186 struct mips_bus_space bonito_memt; 187 struct mips_bus_dma_tag bonito_dmat; 188 struct mips_pci_chipset bonito_pc; 189 190 uint loongson_ver; 191 192 const struct platform *sys_platform; 193 struct bonito_flavour { 194 const char *prefix; 195 const struct platform *platform; 196 }; 197 198 extern const struct platform fuloong_platform; 199 extern const struct platform gdium_platform; 200 extern const struct platform generic2e_platform; 201 extern const struct platform lynloong_platform; 202 extern const struct platform yeeloong_platform; 203 204 const struct bonito_flavour bonito_flavours[] = { 205 /* Lemote Fuloong 2F mini-PC */ 206 { "LM6002", &fuloong_platform }, /* dual Ethernet, no prefix */ 207 { "LM6003", &fuloong_platform }, 208 { "LM6004", &fuloong_platform }, 209 /* EMTEC Gdium Liberty 1000 */ 210 { "Gdium", &gdium_platform }, 211 /* Lemote Yeeloong 8.9" netbook */ 212 { "LM8089", &yeeloong_platform }, 213 /* supposedly Lemote Yeeloong 10.1" netbook, but those found so far 214 report themselves as LM8089 */ 215 { "LM8101", &yeeloong_platform }, 216 /* Lemote Lynloong all-in-one computer */ 217 { "LM9001", &lynloong_platform }, 218 { NULL } 219 }; 220 221 /* Maps for VM objects. */ 222 struct vm_map *phys_map = NULL; 223 224 int netboot; /* Are we netbooting? */ 225 226 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX]; 227 int mem_cluster_cnt; 228 229 void mach_init(int, int32_t, int32_t, int32_t, char *); 230 231 static int pmoncngetc(dev_t); 232 static void pmoncnputc(dev_t, int); 233 234 struct consdev pmoncons = { 235 NULL, /* probe */ 236 NULL, /* init */ 237 pmoncngetc, /* getc */ 238 pmoncnputc, /* putc */ 239 nullcnpollc, /* poolc */ 240 NULL, /* BELL */ 241 makedev(0, 0), 242 CN_DEAD 243 }; 244 245 /* 246 * Do all the stuff that locore normally does before calling main(). 247 */ 248 void 249 mach_init(int32_t argc, int32_t argva, int32_t enva, int32_t callvec, 250 char *boot_esym) 251 { 252 void *kernend; 253 #ifdef NOTYET 254 int howto; 255 #endif 256 const char *env; 257 int i; 258 psize_t memlo, memhi; 259 const struct bonito_flavour *f; 260 char *ssym = NULL, *esym = NULL; 261 pcireg_t reg; 262 pcitag_t pcitag; 263 264 extern char edata[], end[]; 265 266 /* 267 * Clear the BSS segment. 268 */ 269 memset(edata, 0, (char *)end - edata); 270 271 pmon_init(argc, argva, enva, callvec); 272 DPPRINTF(("pmon hello\n")); 273 274 cn_tab = &pmoncons; 275 276 DPRINTF(("hello 0x%x %d 0x%x 0x%x %p stack %p\n", pmon_callvec, argc, argva, enva, boot_esym, &i)); 277 278 /* 279 * Reserve space for the symbol table, if it exists. 280 */ 281 282 #if NKSYMS || defined(DDB) || defined(MODULAR) 283 /* Attempt to locate ELF header and symbol table after kernel. */ 284 if (end[0] == ELFMAG0 && end[1] == ELFMAG1 && 285 end[2] == ELFMAG2 && end[3] == ELFMAG3) { 286 /* ELF header exists directly after kernel. */ 287 ssym = end; 288 esym = boot_esym; 289 kernend = (void *)mips_round_page(esym); 290 } else { 291 ssym = (char *)(vaddr_t)*(int32_t *)end; 292 if (((long)ssym - (long)end) >= 0 && 293 ((long)ssym - (long)end) <= 0x1000 && 294 ssym[0] == ELFMAG0 && ssym[1] == ELFMAG1 && 295 ssym[2] == ELFMAG2 && ssym[3] == ELFMAG3) { 296 /* Pointers exist directly after kernel. */ 297 esym = (char *)(vaddr_t)*((int32_t *)end + 1); 298 kernend = (void *)mips_round_page(esym); 299 } else { 300 /* Pointers aren't setup either... */ 301 ssym = NULL; 302 esym = NULL; 303 kernend = (void *)mips_round_page(end); 304 } 305 } 306 DPRINTF(("ssym %p esym %p\n", ssym, esym)); 307 #endif 308 309 /* 310 * Set up the exception vectors and CPU-specific function 311 * vectors early on. We need the wbflush() vector set up 312 * before comcnattach() is called (or at least before the 313 * first printf() after that is called). 314 * Also clears the I+D caches. 315 */ 316 DPRINTF(("mips_vector_init ")); 317 mips_vector_init(NULL, false); 318 319 DPRINTF(("uvm_md_init\n")); 320 uvm_md_init(); 321 #if NKSYMS || defined(DDB) || defined(MODULAR) 322 //ksyms_addsyms_elf((vaddr_t)esym - (vaddr_t)ssym, ssym, esym); 323 #endif 324 325 /* 326 * Try and figure out what kind of hardware we are. 327 */ 328 329 env = pmon_getenv("systype"); 330 if (env == NULL) { 331 printf("Unable to figure out system type!\n"); 332 goto unsupported; 333 } 334 if (strcmp(env, "Bonito") != 0) { 335 printf("This kernel doesn't support system type \"%s\".\n", 336 env); 337 goto unsupported; 338 } 339 340 /* 341 * While the kernel supports other processor types than Loongson, 342 * we are not expecting a Bonito-based system with a different 343 * processor. Just to be on the safe side, refuse to run on 344 * non Loongson2 processors for now. 345 */ 346 347 switch ((mips_options.mips_cpu_id >> 8) & 0xff) { 348 case MIPS_LOONGSON2: 349 switch (mips_options.mips_cpu_id & 0xff) { 350 case 0x00: 351 loongson_ver = 0x2c; 352 break; 353 case 0x02: 354 loongson_ver = 0x2e; 355 break; 356 case 0x03: 357 loongson_ver = 0x2f; 358 break; 359 case 0x05: 360 loongson_ver = 0x3a; 361 break; 362 } 363 if (loongson_ver == 0x2e || loongson_ver == 0x2f) 364 break; 365 /* FALLTHROUGH */ 366 default: 367 printf("This kernel doesn't support processor type 0x%x" 368 ", version %d.%d.\n", 369 (mips_options.mips_cpu_id >> 8) & 0xff, 370 (mips_options.mips_cpu_id >> 4) & 0x0f, 371 mips_options.mips_cpu_id & 0x0f); 372 goto unsupported; 373 } 374 375 /* 376 * Try to figure out what particular machine we run on, depending 377 * on the PMON version information. 378 */ 379 380 env = pmon_getenv("Version"); 381 if (env == NULL) { 382 /* 383 * If this is a 2E system, use the generic code and hope 384 * for the best. 385 */ 386 if (loongson_ver == 0x2e) { 387 sys_platform = &generic2e_platform; 388 } else { 389 printf("Unable to figure out model!\n"); 390 goto unsupported; 391 } 392 } else { 393 for (f = bonito_flavours; f->prefix != NULL; f++) 394 if (strncmp(env, f->prefix, strlen(f->prefix)) == 395 0) { 396 sys_platform = f->platform; 397 break; 398 } 399 400 if (sys_platform == NULL) { 401 /* 402 * Early Lemote designs shipped without a model prefix. 403 * Hopefully these well be close enough to the first 404 * generation Fuloong 2F design (LM6002); let's warn 405 * the user and try this if version is 1.2.something 406 * (1.3 onwards are expected to have a model prefix, 407 * and there are currently no reports of 1.1 and 408 * below being 2F systems). 409 * 410 * Note that this could be handled by adding a 411 * "1.2." machine type entry to the flavours table, 412 * but I prefer have it stand out. 413 * LM6002 users are encouraged to add the system 414 * model prefix to the `Version' variable. 415 */ 416 if (strncmp(env, "1.2.", 4) == 0) { 417 printf("No model prefix in version" 418 " string \"%s\".\n" 419 "Attempting to match as Lemote Fuloong\n", 420 env); 421 sys_platform = &fuloong_platform; 422 } 423 } 424 425 if (sys_platform == NULL) { 426 printf("This kernel doesn't support model \"%s\"." 427 "\n", env); 428 goto unsupported; 429 } 430 } 431 432 cpu_setmodel("%s %s", sys_platform->vendor, sys_platform->product); 433 DPRINTF(("Found %s, setting up.\n", cpu_getmodel())); 434 435 /* 436 * Figure out memory information. 437 * PMON reports it in two chunks, the memory under the 256MB 438 * CKSEG limit, and memory above that limit. We need to do the 439 * math ourselves. 440 */ 441 442 env = pmon_getenv("memsize"); 443 if (env == NULL) { 444 printf("Could not get memory information" 445 " from the firmware\n"); 446 goto unsupported; 447 } 448 memlo = strtoul(env, NULL, 10); /* size in MB */ 449 DPRINTF(("memlo %" PRIdPSIZE, memlo)); 450 if (memlo < 0 || memlo > 256) { 451 printf("Incorrect low memory size `%s'\n", env); 452 goto unsupported; 453 } 454 455 /* 3A PMON only reports up to 240MB as low memory */ 456 if (memlo >= 240) { 457 env = pmon_getenv("highmemsize"); 458 if (env == NULL) 459 memhi = 0; 460 else 461 memhi = strtoul(env, NULL, 10); /* size in MB */ 462 if (memhi < 0 || memhi > (64 * 1024) - 256) { 463 printf("Incorrect high memory size `%s'\n", 464 env); 465 /* better expose the problem than limit to 256MB */ 466 goto unsupported; 467 } 468 } else 469 memhi = 0; 470 471 DPRINTF(("memhi %" PRIdPSIZE "\n", memhi)); 472 memlo = memlo * 1024 * 1024; 473 memhi = memhi * 1024 * 1024; 474 475 switch (loongson_ver) { 476 case 0x2e: 477 loongson2e_setup(memlo, memhi, 478 MIPS_KSEG0_START, (vaddr_t)kernend, &bonito_dmat); 479 break; 480 default: 481 case 0x2f: 482 case 0x3a: 483 loongson2f_setup(memlo, memhi, 484 MIPS_KSEG0_START, (vaddr_t)kernend, &bonito_dmat); 485 break; 486 } 487 488 DPRINTF(("bonito_pci_init ")); 489 bonito_pci_init(&bonito_pc, sys_platform->bonito_config); 490 bonito_pc.pc_intr_v = __UNCONST(sys_platform->bonito_config); 491 bonito_pc.pc_intr_map = loongson_pci_intr_map; 492 bonito_pc.pc_intr_string = loongson_pci_intr_string; 493 bonito_pc.pc_intr_evcnt = loongson_pci_intr_evcnt; 494 bonito_pc.pc_intr_establish = loongson_pci_intr_establish; 495 bonito_pc.pc_intr_disestablish = loongson_pci_intr_disestablish; 496 bonito_pc.pc_conf_interrupt = loongson_pci_conf_interrupt; 497 bonito_pc.pc_pciide_compat_intr_establish = 498 loongson_pciide_compat_intr_establish; 499 DPRINTF(("bonito_bus_io_init ")); 500 bonito_bus_io_init(&bonito_iot, NULL); 501 /* override mapping function */ 502 bonito_iot.bs_map = bonito_bus_io_legacy_map; 503 DPRINTF(("bonito_bus_mem_init\n")); 504 bonito_bus_mem_init(&bonito_memt, NULL); 505 506 bonito_dmat._cookie = __UNCONST(sys_platform); 507 bonito_dmat._dmamap_ops = mips_bus_dmamap_ops; 508 bonito_dmat._dmamem_ops = mips_bus_dmamem_ops; 509 bonito_dmat._dmatag_ops = mips_bus_dmatag_ops; 510 511 DPRINTF(("sys_platform->setup %p\n", sys_platform->setup)); 512 if (sys_platform->setup != NULL) 513 (*(sys_platform->setup))(); 514 515 #if NCOM > 0 516 DPRINTF(("comconsrate %d\n", comconsrate)); 517 if (comconsrate > 0) { 518 if (comcnattach(comconsiot, comconsaddr, comconsrate, 519 COM_FREQ, COM_TYPE_NORMAL, 520 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 521 panic("unable to initialize serial console"); 522 } 523 #endif /* NCOM > 0 */ 524 525 for (i = 0; i < 32 - 0x11; i++) { 526 pcitag = pci_make_tag(&bonito_pc, 0, i, 0); 527 reg = pci_conf_read(&bonito_pc, pcitag, PCI_CLASS_REG); 528 DPRINTF(("dev %d class 0x%x", i, reg)); 529 reg = pci_conf_read(&bonito_pc, pcitag, PCI_ID_REG); 530 DPRINTF((" id 0x%x; ", reg)); 531 #if NSISFB > 0 532 if (cn_tab == &pmoncons) 533 sisfb_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 534 pcitag, reg); 535 #endif 536 #if NLYNXFB > 0 537 if (cn_tab == &pmoncons) 538 lynxfb_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 539 pcitag, reg); 540 #endif 541 if (cn_tab == &pmoncons) 542 gdium_cnattach(&bonito_memt, &bonito_iot, &bonito_pc, 543 pcitag, reg); 544 if (cn_tab != &pmoncons) 545 break; 546 } 547 #if NPCKBC > 0 || NUKBD > 0 548 if (cn_tab != &pmoncons) { 549 int rc = ENXIO; 550 #if NPCKBC > 0 551 if (rc != 0) 552 rc = pckbc_cnattach(&bonito_iot, IO_KBD, KBCMDP, 0, 0); 553 #endif 554 #if NUKBD > 0 555 if (rc != 0) 556 rc = ukbd_cnattach(); 557 #endif 558 } 559 #endif /* NPCKBC > 0 || NUKBD > 0 */ 560 DPRINTF(("\n")); 561 562 /* 563 * Get the timer from PMON. 564 */ 565 DPRINTF(("search cpuclock ")); 566 env = pmon_getenv("cpuclock"); 567 DPRINTF(("got %s ", env)); 568 if (env != NULL) { 569 curcpu()->ci_cpu_freq = 570 strtoul(env, NULL, 10); 571 } 572 573 DPRINTF(("cpuclock %ld\n", curcpu()->ci_cpu_freq)); 574 575 if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 576 curcpu()->ci_cpu_freq /= 2; 577 578 579 /* Compute the number of ticks for hz. */ 580 curcpu()->ci_cycles_per_hz = (curcpu()->ci_cpu_freq + hz / 2) / hz; 581 582 /* Compute the delay divisor. */ 583 curcpu()->ci_divisor_delay = 584 ((curcpu()->ci_cpu_freq + 500000) / 1000000); 585 586 /* 587 * Get correct cpu frequency if the CPU runs at twice the 588 * external/cp0-count frequency. 589 */ 590 if (mips_options.mips_cpu_flags & CPU_MIPS_DOUBLE_COUNT) 591 curcpu()->ci_cpu_freq *= 2; 592 593 #ifdef DEBUG 594 printf("Timer calibration: %lu cycles/sec\n", 595 curcpu()->ci_cpu_freq); 596 #endif 597 598 #if NCOM > 0 && 0 599 /* 600 * Delay to allow firmware putchars to complete. 601 * FIFO depth * character time. 602 * character time = (1000000 / (defaultrate / 10)) 603 */ 604 delay(160000000 / comcnrate); 605 if (comcnattach(&gc->gc_iot, MALTA_UART0ADR, comcnrate, 606 COM_FREQ, COM_TYPE_NORMAL, 607 (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8) != 0) 608 panic("malta: unable to initialize serial console"); 609 #endif /* NCOM > 0 */ 610 611 /* 612 * XXX: check argv[0] - do something if "gdb"??? 613 */ 614 615 /* 616 * Look at arguments passed to us and compute boothowto. 617 */ 618 boothowto = RB_AUTOBOOT; 619 #ifdef NOTYET 620 for (i = 1; i < argc; i++) { 621 for (cp = argv[i]; *cp; cp++) { 622 /* Ignore superfluous '-', if there is one */ 623 if (*cp == '-') 624 continue; 625 626 howto = 0; 627 BOOT_FLAG(*cp, howto); 628 if (! howto) 629 printf("bootflag '%c' not recognised\n", *cp); 630 else 631 boothowto |= howto; 632 } 633 } 634 #endif 635 636 /* 637 * Load the rest of the available pages into the VM system. 638 */ 639 mips_page_physload(MIPS_KSEG0_START, (vaddr_t)kernend, 640 mem_clusters, mem_cluster_cnt, NULL, 0); 641 642 /* 643 * Initialize error message buffer (at end of core). 644 */ 645 DPRINTF(("mips_init_msgbuf\n")); 646 mips_init_msgbuf(); 647 648 DPRINTF(("pmap_bootstrap\n")); 649 pmap_bootstrap(); 650 651 /* 652 * Allocate uarea page for lwp0 and set it. 653 */ 654 DPRINTF(("curlwp %p ", curlwp)); 655 DPRINTF(("curlwp stack %p\n", curlwp->l_addr)); 656 mips_init_lwp0_uarea(); 657 658 DPRINTF(("curlwp %p ", curlwp)); 659 DPRINTF(("curlwp stack %p\n", curlwp->l_addr)); 660 661 /* 662 * Initialize debuggers, and break into them, if appropriate. 663 */ 664 #if defined(DDB) 665 if (boothowto & RB_KDB) 666 Debugger(); 667 #endif 668 DPRINTF(("return\n")); 669 return; 670 unsupported: 671 panic("unsupported hardware\n"); 672 } 673 674 void 675 consinit(void) 676 { 677 678 /* 679 * Everything related to console initialization is done 680 * in mach_init(). 681 */ 682 } 683 684 /* 685 * Allocate memory for variable-sized tables, 686 */ 687 void 688 cpu_startup(void) 689 { 690 /* 691 * Do the common startup items. 692 */ 693 cpu_startup_common(); 694 695 /* 696 * Virtual memory is bootstrapped -- notify the bus spaces 697 * that memory allocation is now safe. 698 */ 699 ex_mallocsafe = 1; 700 } 701 702 int waittime = -1; 703 704 void 705 cpu_reboot(int howto, char *bootstr) 706 { 707 708 /* Take a snapshot before clobbering any registers. */ 709 savectx(curpcb); 710 711 if (cold) { 712 howto |= RB_HALT; 713 goto haltsys; 714 } 715 716 /* If "always halt" was specified as a boot flag, obey. */ 717 if (boothowto & RB_HALT) 718 howto |= RB_HALT; 719 720 boothowto = howto; 721 if ((howto & RB_NOSYNC) == 0 && (waittime < 0)) { 722 waittime = 0; 723 vfs_shutdown(); 724 725 /* 726 * If we've been adjusting the clock, the todr 727 * will be out of synch; adjust it now. 728 */ 729 resettodr(); 730 } 731 732 splhigh(); 733 734 if (howto & RB_DUMP) 735 dumpsys(); 736 737 haltsys: 738 doshutdownhooks(); 739 740 pmf_system_shutdown(boothowto); 741 742 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) { 743 if (sys_platform->powerdown != NULL) 744 sys_platform->powerdown(); 745 } 746 747 if (howto & RB_HALT) { 748 printf("\n"); 749 printf("The operating system has halted.\n"); 750 printf("Please press any key to reboot.\n\n"); 751 cnpollc(1); /* For proper keyboard command handling */ 752 cngetc(); 753 cnpollc(0); 754 } 755 756 printf("%s\n\n", ((howto & RB_HALT) != 0) ? "halted." : "rebooting..."); 757 758 if (sys_platform->reset != NULL) 759 sys_platform->reset(); 760 761 __asm__ __volatile__ ( 762 "\t.long 0x3c02bfc0\n" 763 "\t.long 0x00400008\n" 764 ::: "v0"); 765 } 766 767 /* 768 * Early console through pmon routines. 769 */ 770 771 int 772 pmoncngetc(dev_t dev) 773 { 774 /* 775 * PMON does not give us a getc routine. So try to get a whole line 776 * and return it char by char, trying not to lose the \n. Kind 777 * of ugly but should work. 778 * 779 * Note that one could theoretically use pmon_read(STDIN, &c, 1) 780 * but the value of STDIN within PMON is not a constant and there 781 * does not seem to be a way of letting us know which value to use. 782 */ 783 static char buf[1 + PMON_MAXLN]; 784 static char *bufpos = buf; 785 int c; 786 787 if (*bufpos == '\0') { 788 bufpos = buf; 789 if (pmon_gets(buf) == NULL) { 790 /* either an empty line or EOF. assume the former */ 791 return (int)'\n'; 792 } else { 793 /* put back the \n sign */ 794 buf[strlen(buf)] = '\n'; 795 } 796 } 797 798 c = (int)*bufpos++; 799 if (bufpos - buf > PMON_MAXLN) { 800 bufpos = buf; 801 *bufpos = '\0'; 802 } 803 804 return c; 805 } 806 807 void 808 pmoncnputc(dev_t dev, int c) 809 { 810 if (c == '\n') 811 pmon_printf("\n"); 812 else 813 pmon_printf("%c", c); 814 } 815