1 /* $NetBSD: machdep.c,v 1.67 2016/12/22 16:05:14 cherry Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1986, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * from: Utah $Hdr: machdep.c 1.74 92/12/20$ 37 * 38 * @(#)machdep.c 8.10 (Berkeley) 4/20/94 39 */ 40 41 #include <sys/cdefs.h> 42 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.67 2016/12/22 16:05:14 cherry Exp $"); 43 44 #include "opt_bufcache.h" 45 #include "opt_ddb.h" 46 #include "opt_kgdb.h" 47 #include "opt_compat_netbsd.h" 48 #include "opt_sysv.h" 49 #include "opt_panicbutton.h" 50 #include "opt_modular.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/buf.h> 55 #include <sys/callout.h> 56 #include <sys/conf.h> 57 #include <sys/exec.h> 58 #include <sys/exec_aout.h> /* for MID_* */ 59 #include <sys/file.h> 60 #include <sys/ioctl.h> 61 #include <sys/kernel.h> 62 #include <sys/malloc.h> 63 #include <sys/mbuf.h> 64 #include <sys/mount.h> 65 #include <sys/msgbuf.h> 66 #include <sys/proc.h> 67 #include <sys/reboot.h> 68 #include <sys/signalvar.h> 69 #include <sys/syscallargs.h> 70 #include <sys/tty.h> 71 #include <sys/vnode.h> 72 #include <sys/ksyms.h> 73 #include <sys/module.h> 74 #include <sys/cpu.h> 75 #include <sys/kgdb.h> 76 77 #include <machine/db_machdep.h> 78 #include <ddb/db_sym.h> 79 #include <ddb/db_extern.h> 80 81 #include <machine/autoconf.h> 82 #include <machine/cpu.h> 83 #include <machine/reg.h> 84 #include <machine/pcb.h> 85 #include <machine/psl.h> 86 #include <machine/pte.h> 87 88 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 89 90 #include <uvm/uvm_extern.h> 91 92 #include <sys/sysctl.h> 93 #include <sys/device.h> 94 #include <dev/cons.h> 95 #include <dev/mm.h> 96 #include <dev/ic/z8530reg.h> 97 #include <machine/z8530var.h> 98 #include <cesfic/dev/zsvar.h> 99 100 #include "ksyms.h" 101 102 /* the following is used externally (sysctl_hw) */ 103 char machine[] = MACHINE; /* CPU "architecture" */ 104 105 /* Our exported CPU info; we can have only one. */ 106 struct cpu_info cpu_info_store; 107 108 struct vm_map *phys_map = NULL; 109 110 /* 111 * Declare these as initialized data so we can patch them. 112 */ 113 /*int maxmem;*/ /* max memory per process */ 114 extern psize_t physmem; /* max supported memory, changes to actual */ 115 116 extern u_int lowram; 117 118 void fic_init(void); 119 120 /* prototypes for local functions */ 121 void identifycpu(void); 122 void dumpmem(int *, int, int); 123 char *hexstr(int, int); 124 125 /* functions called from locore.s */ 126 void dumpsys(void); 127 void straytrap(int, u_short); 128 void nmihand(struct frame); 129 130 int delay_divisor; /* delay constant */ 131 132 extern void sicinit(void*); 133 134 void fic_init(void) 135 { 136 int i; 137 138 extern paddr_t avail_start, avail_end; 139 140 boothowto = RB_SINGLE; /* XXX for now */ 141 boothowto |= RB_KDB; /* XXX for now */ 142 143 delay_divisor = 30; /* XXX */ 144 145 /* 146 * Tell the VM system about available physical memory. The 147 * fic uses one segment. 148 */ 149 uvm_page_physload(atop(avail_start), atop(avail_end), 150 atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT); 151 152 /* 153 * map and init interrupt controller 154 */ 155 physaccess((void*)virtual_avail, (void*)0x44000000, 156 PAGE_SIZE, PG_RW|PG_CI); 157 sicinit((void*)virtual_avail); 158 virtual_avail += PAGE_SIZE; 159 160 /* 161 * Initialize error message buffer (at end of core). 162 * avail_end was pre-decremented in pmap_bootstrap to compensate. 163 */ 164 for (i = 0; i < btoc(MSGBUFSIZE); i++) 165 pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE, 166 avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 167 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED); 168 pmap_update(pmap_kernel()); 169 initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE)); 170 } 171 172 int 173 zs_check_kgdb(struct zs_chanstate *cs, int dev) 174 { 175 176 if((boothowto & RB_KDB) && (dev == makedev(10, 0))) 177 return (1); 178 return (0); 179 } 180 181 void zs_kgdb_cnputc(dev_t, int); 182 void zs_kgdb_cnputc(dev_t dev, int c) 183 { 184 zscnputc(dev, c); 185 } 186 int zs_kgdb_cngetc(dev_t); 187 int zs_kgdb_cngetc(dev_t dev) 188 { 189 return (zscngetc(dev)); 190 } 191 192 /* 193 * Console initialization: called early on from main, 194 * before vm init or startup. Do enough configuration 195 * to choose and initialize a console. 196 */ 197 extern void sic_enable_int(int, int, int, int, int); 198 void 199 consinit(void) 200 { 201 202 /* 203 * Initialize the console before we print anything out. 204 */ 205 physaccess((void*)virtual_avail, 206 (void*)0x58000000, PAGE_SIZE, PG_RW|PG_CI); 207 zs_cnattach((void*)virtual_avail); 208 virtual_avail += PAGE_SIZE; 209 210 #ifdef KGDB 211 kgdb_dev = 1; 212 kgdb_attach((void*)zscngetc, (void*)zscnputc, (void *)0); 213 214 if (boothowto & RB_KDB) { 215 kgdb_connect(1); 216 zscons.cn_putc = zs_kgdb_cnputc; 217 zscons.cn_getc = zs_kgdb_cngetc; 218 } 219 #endif 220 #ifdef DDB 221 if (boothowto & RB_KDB) 222 Debugger(); 223 #endif 224 sic_enable_int(39, 2, 1, 7, 0); /* NMI */ 225 } 226 227 /* 228 * cpu_startup: allocate memory for variable-sized tables, 229 * initialize CPU, and do autoconfiguration. 230 */ 231 void 232 cpu_startup(void) 233 { 234 vaddr_t minaddr, maxaddr; 235 #ifdef DEBUG 236 extern int pmapdebug; 237 int opmapdebug = pmapdebug; 238 239 pmapdebug = 0; 240 #endif 241 242 cpu_setmodel("FIC8234"); 243 if (fputype != FPU_NONE) 244 m68k_make_fpu_idle_frame(); 245 246 /* 247 * Good {morning,afternoon,evening,night}. 248 */ 249 printf("%s%s", copyright, version); 250 identifycpu(); 251 printf("real mem = %d\n", ctob(physmem)); 252 253 minaddr = 0; 254 255 /* 256 * Allocate a submap for physio 257 */ 258 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, 259 VM_PHYS_SIZE, 0, false, NULL); 260 261 #ifdef DEBUG 262 pmapdebug = opmapdebug; 263 #endif 264 printf("avail mem = %ld\n", ptoa(uvmexp.free)); 265 } 266 267 /* 268 * Info for CTL_HW 269 */ 270 271 void 272 identifycpu(void) 273 { 274 printf("%s\n", cpu_getmodel()); 275 printf("delay constant: %d\n", delay_divisor); 276 } 277 278 /* 279 * machine dependent system variables. 280 */ 281 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 282 { 283 284 sysctl_createv(clog, 0, NULL, NULL, 285 CTLFLAG_PERMANENT, 286 CTLTYPE_NODE, "machdep", NULL, 287 NULL, 0, NULL, 0, 288 CTL_MACHDEP, CTL_EOL); 289 290 sysctl_createv(clog, 0, NULL, NULL, 291 CTLFLAG_PERMANENT, 292 CTLTYPE_STRUCT, "console_device", NULL, 293 sysctl_consdev, 0, NULL, sizeof(dev_t), 294 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 295 } 296 297 int waittime = -1; 298 299 void 300 cpu_reboot(int howto, char *bootstr) 301 { 302 struct pcb *pcb = lwp_getpcb(curlwp); 303 304 /* take a snap shot before clobbering any registers */ 305 if (pcb != NULL) 306 savectx(pcb); 307 308 /* If system is cold, just halt. */ 309 if (cold) { 310 howto |= RB_HALT; 311 goto haltsys; 312 } 313 314 boothowto = howto; 315 if ((howto & RB_NOSYNC) == 0 && waittime < 0) { 316 waittime = 0; 317 vfs_shutdown(); 318 /* 319 * If we've been adjusting the clock, the todr 320 * will be out of synch; adjust it now. 321 */ 322 resettodr(); 323 } 324 325 /* Disable interrupts. */ 326 splhigh(); 327 328 /* If rebooting and a dump is requested do it. */ 329 if (howto & RB_DUMP) 330 dumpsys(); 331 332 haltsys: 333 /* Run any shutdown hooks. */ 334 doshutdownhooks(); 335 336 pmf_system_shutdown(boothowto); 337 338 #if defined(PANICWAIT) && !defined(DDB) 339 if ((howto & RB_HALT) == 0 && panicstr) { 340 printf("hit any key to reboot...\n"); 341 (void)cngetc(); 342 printf("\n"); 343 } 344 #endif 345 346 /* Finally, halt/reboot the system. */ 347 if (howto & RB_HALT) { 348 printf("System halted. Hit any key to reboot.\n\n"); 349 (void)cngetc(); 350 } 351 352 printf("rebooting...\n"); 353 DELAY(1000000); 354 doboot(); 355 /*NOTREACHED*/ 356 } 357 358 /* 359 * These variables are needed by /sbin/savecore 360 */ 361 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 362 int dumpsize = 0; /* pages */ 363 long dumplo = 0; /* blocks */ 364 365 /* 366 * This is called by main to set dumplo and dumpsize. 367 * Dumps always skip the first CLBYTES of disk space 368 * in case there might be a disk label stored there. 369 * If there is extra space, put dump at the end to 370 * reduce the chance that swapping trashes it. 371 */ 372 void 373 cpu_dumpconf(void) 374 { 375 int nblks; /* size of dump area */ 376 377 if (dumpdev == NODEV) 378 return; 379 nblks = bdev_size(dumpdev); 380 if (nblks <= ctod(1)) 381 return; 382 383 /* 384 * XXX include the final RAM page which is not included in physmem. 385 */ 386 dumpsize = physmem + 1; 387 388 /* Always skip the first CLBYTES, in case there is a label there. */ 389 if (dumplo < ctod(1)) 390 dumplo = ctod(1); 391 392 /* Put dump at end of partition, and make it fit. */ 393 if (dumpsize > dtoc(nblks - dumplo)) 394 dumpsize = dtoc(nblks - dumplo); 395 if (dumplo < nblks - ctod(dumpsize)) 396 dumplo = nblks - ctod(dumpsize); 397 } 398 399 /* 400 * Dump physical memory onto the dump device. Called by doadump() 401 * in locore.s or by cpu_reboot() here in machdep.c 402 */ 403 void 404 dumpsys(void) 405 { 406 const struct bdevsw *bdev; 407 daddr_t blkno; /* current block to write */ 408 /* dump routine */ 409 int (*dump)(dev_t, daddr_t, void *, size_t); 410 int pg; /* page being dumped */ 411 vm_offset_t maddr; /* PA being dumped */ 412 int error; /* error code from (*dump)() */ 413 414 /* Don't put dump messages in msgbuf. */ 415 msgbufmapped = 0; 416 417 /* Make sure dump device is valid. */ 418 if (dumpdev == NODEV) 419 return; 420 bdev = bdevsw_lookup(dumpdev); 421 if (bdev == NULL) 422 return; 423 if (dumpsize == 0) { 424 cpu_dumpconf(); 425 if (dumpsize == 0) 426 return; 427 } 428 if (dumplo < 0) 429 return; 430 dump = bdev->d_dump; 431 blkno = dumplo; 432 433 printf("\ndumping to dev %"PRIx64", offset %ld\n", dumpdev, dumplo); 434 435 printf("dump "); 436 maddr = lowram; 437 for (pg = 0; pg < dumpsize; pg++) { 438 #define NPGMB (1024*1024/PAGE_SIZE) 439 /* print out how many MBs we have dumped */ 440 if (pg && (pg % NPGMB) == 0) 441 printf("%d ", pg / NPGMB); 442 #undef NPGMB 443 pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr, 444 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 445 pmap_update(pmap_kernel()); 446 447 error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE); 448 switch (error) { 449 case 0: 450 maddr += PAGE_SIZE; 451 blkno += btodb(PAGE_SIZE); 452 break; 453 454 case ENXIO: 455 printf("device bad\n"); 456 return; 457 458 case EFAULT: 459 printf("device not ready\n"); 460 return; 461 462 case EINVAL: 463 printf("area improper\n"); 464 return; 465 466 case EIO: 467 printf("i/o error\n"); 468 return; 469 470 case EINTR: 471 printf("aborted from console\n"); 472 return; 473 474 default: 475 printf("error %d\n", error); 476 return; 477 } 478 } 479 printf("succeeded\n"); 480 } 481 482 void 483 straytrap(int pc, u_short evec) 484 { 485 printf("unexpected trap (vector offset %x) from %x\n", 486 evec & 0xFFF, pc); 487 } 488 489 /* XXX should change the interface, and make one badaddr() function */ 490 491 int *nofault; 492 493 int 494 badaddr(void *addr) 495 { 496 int i; 497 label_t faultbuf; 498 499 nofault = (int *) &faultbuf; 500 if (setjmp((label_t *)nofault)) { 501 nofault = (int *) 0; 502 return (1); 503 } 504 i = *(volatile short *)addr; 505 __USE(i); 506 nofault = (int *) 0; 507 return (0); 508 } 509 510 int 511 badbaddr(void *addr) 512 { 513 int i; 514 label_t faultbuf; 515 516 nofault = (int *) &faultbuf; 517 if (setjmp((label_t *)nofault)) { 518 nofault = (int *) 0; 519 return (1); 520 } 521 i = *(volatile char *)addr; 522 __USE(i); 523 nofault = (int *) 0; 524 return (0); 525 } 526 527 #ifdef PANICBUTTON 528 /* 529 * Declare these so they can be patched. 530 */ 531 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 532 int candbdiv = 2; /* give em half a second (hz / candbdiv) */ 533 534 void candbtimer(void *); 535 536 int crashandburn; 537 538 void 539 candbtimer(void *arg) 540 { 541 542 crashandburn = 0; 543 } 544 #endif /* PANICBUTTON */ 545 546 static int innmihand; /* simple mutex */ 547 548 /* 549 * Level 7 interrupts can be caused by the keyboard or parity errors. 550 */ 551 void 552 nmihand(struct frame frame) 553 { 554 555 /* Prevent unwanted recursion. */ 556 if (innmihand) 557 return; 558 innmihand = 1; 559 560 printf("NMI\n"); 561 #if defined(DDB) || defined(KGDB) 562 Debugger(); 563 #endif 564 565 innmihand = 0; 566 } 567 568 569 /* 570 * cpu_exec_aout_makecmds(): 571 * CPU-dependent a.out format hook for execve(). 572 * 573 * Determine of the given exec package refers to something which we 574 * understand and, if so, set up the vmcmds for it. 575 * 576 * XXX what are the special cases for the hp300? 577 * XXX why is this COMPAT_NOMID? was something generating 578 * hp300 binaries with an a_mid of 0? i thought that was only 579 * done on little-endian machines... -- cgd 580 */ 581 int 582 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp) 583 { 584 #if defined(COMPAT_NOMID) || defined(COMPAT_44) 585 u_long midmag, magic; 586 u_short mid; 587 int error; 588 struct exec *execp = epp->ep_hdr; 589 590 midmag = ntohl(execp->a_midmag); 591 mid = (midmag >> 16) & 0xffff; 592 magic = midmag & 0xffff; 593 594 midmag = mid << 16 | magic; 595 596 switch (midmag) { 597 #ifdef COMPAT_NOMID 598 case (MID_ZERO << 16) | ZMAGIC: 599 error = exec_aout_prep_oldzmagic(l, epp); 600 return (error); 601 #endif 602 #ifdef COMPAT_44 603 case (MID_HP300 << 16) | ZMAGIC: 604 error = exec_aout_prep_oldzmagic(l, epp); 605 return (error); 606 #endif 607 } 608 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */ 609 610 return ENOEXEC; 611 } 612 613 int 614 mm_md_physacc(paddr_t pa, vm_prot_t prot) 615 { 616 617 return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0; 618 } 619 620 #ifdef MODULAR 621 /* 622 * Push any modules loaded by the bootloader etc. 623 */ 624 void 625 module_init_md(void) 626 { 627 } 628 #endif 629