1 /* $NetBSD: machdep.c,v 1.94 2026/04/28 03:29:09 thorpej 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.94 2026/04/28 03:29:09 thorpej Exp $"); 43 44 #include "opt_bufcache.h" 45 #include "opt_ddb.h" 46 #include "opt_kgdb.h" 47 #include "opt_sysv.h" 48 #include "opt_panicbutton.h" 49 #include "opt_modular.h" 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/buf.h> 54 #include <sys/callout.h> 55 #include <sys/conf.h> 56 #include <sys/exec.h> 57 #include <sys/file.h> 58 #include <sys/ioctl.h> 59 #include <sys/kernel.h> 60 #include <sys/mbuf.h> 61 #include <sys/mount.h> 62 #include <sys/msgbuf.h> 63 #include <sys/proc.h> 64 #include <sys/reboot.h> 65 #include <sys/signalvar.h> 66 #include <sys/syscallargs.h> 67 #include <sys/tty.h> 68 #include <sys/vnode.h> 69 #include <sys/ksyms.h> 70 #include <sys/module.h> 71 #include <sys/cpu.h> 72 #include <sys/kgdb.h> 73 74 #include <machine/db_machdep.h> 75 #include <ddb/db_sym.h> 76 #include <ddb/db_extern.h> 77 78 #include <machine/autoconf.h> 79 #include <machine/cpu.h> 80 #include <machine/reg.h> 81 #include <machine/pcb.h> 82 #include <machine/psl.h> 83 #include <machine/pte.h> 84 85 #include <m68k/seglist.h> 86 87 #define MAXMEM 64*1024 /* XXX - from cmap.h */ 88 89 #include <uvm/uvm_extern.h> 90 91 #include <sys/sysctl.h> 92 #include <sys/device.h> 93 #include <dev/cons.h> 94 #include <dev/mm.h> 95 #include <dev/ic/z8530reg.h> 96 #include <machine/z8530var.h> 97 #include <cesfic/dev/zsvar.h> 98 99 #include "ksyms.h" 100 101 extern u_int lowram; 102 103 void machine_init(paddr_t); 104 105 /* prototypes for local functions */ 106 char *hexstr(int, int); 107 108 /* functions called from locore.s */ 109 void dumpsys(void); 110 void nmihand(struct frame); 111 112 int delay_divisor; /* delay constant */ 113 114 extern void sicinit(void*); 115 116 struct pmap_bootmap machine_bootmap[] = { 117 /* XXX */ 118 { .pmbm_vaddr = -1 }, 119 }; 120 121 void 122 machine_init(paddr_t nextpa) 123 { 124 boothowto = RB_SINGLE; /* XXX for now */ 125 boothowto |= RB_KDB; /* XXX for now */ 126 127 delay_divisor = delay_divisor_est40(25); /* XXX */ 128 129 phys_seg_list[0].ps_start = lowram; 130 phys_seg_list[0].ps_end = lowram + m68k_ptob(physmem); 131 132 machine_init_common(nextpa); 133 134 /* 135 * map and init interrupt controller 136 */ 137 physaccess((void*)virtual_avail, (void*)0x44000000, 138 PAGE_SIZE, PG_RW|PG_CI); 139 sicinit((void*)virtual_avail); 140 virtual_avail += PAGE_SIZE; 141 } 142 143 int 144 zs_check_kgdb(struct zs_chanstate *cs, int dev) 145 { 146 147 if((boothowto & RB_KDB) && (dev == makedev(10, 0))) 148 return (1); 149 return (0); 150 } 151 152 void zs_kgdb_cnputc(dev_t, int); 153 void zs_kgdb_cnputc(dev_t dev, int c) 154 { 155 zscnputc(dev, c); 156 } 157 int zs_kgdb_cngetc(dev_t); 158 int zs_kgdb_cngetc(dev_t dev) 159 { 160 return (zscngetc(dev)); 161 } 162 163 /* 164 * Console initialization: called early on from main, 165 * before vm init or startup. Do enough configuration 166 * to choose and initialize a console. 167 */ 168 extern void sic_enable_int(int, int, int, int, int); 169 void 170 consinit(void) 171 { 172 173 /* 174 * Initialize the console before we print anything out. 175 */ 176 physaccess((void*)virtual_avail, 177 (void*)0x58000000, PAGE_SIZE, PG_RW|PG_CI); 178 zs_cnattach((void*)virtual_avail); 179 virtual_avail += PAGE_SIZE; 180 181 #ifdef KGDB 182 kgdb_dev = 1; 183 kgdb_attach((void*)zscngetc, (void*)zscnputc, (void *)0); 184 185 if (boothowto & RB_KDB) { 186 kgdb_connect(1); 187 zscons.cn_putc = zs_kgdb_cnputc; 188 zscons.cn_getc = zs_kgdb_cngetc; 189 } 190 #endif 191 #ifdef DDB 192 if (boothowto & RB_KDB) 193 Debugger(); 194 #endif 195 sic_enable_int(39, 2, 1, 7, 0); /* NMI */ 196 } 197 198 /* 199 * cpu_startup: allocate memory for variable-sized tables, 200 * initialize CPU, and do autoconfiguration. 201 */ 202 void 203 cpu_startup(void) 204 { 205 cpu_startup_common(); 206 207 printf("delay constant: %d\n", delay_divisor); 208 } 209 210 void 211 machine_set_model(void) 212 { 213 cpu_setmodel("FIC8234"); 214 } 215 216 /* 217 * machine dependent system variables. 218 */ 219 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup") 220 { 221 222 sysctl_createv(clog, 0, NULL, NULL, 223 CTLFLAG_PERMANENT, 224 CTLTYPE_NODE, "machdep", NULL, 225 NULL, 0, NULL, 0, 226 CTL_MACHDEP, CTL_EOL); 227 228 sysctl_createv(clog, 0, NULL, NULL, 229 CTLFLAG_PERMANENT, 230 CTLTYPE_STRUCT, "console_device", NULL, 231 sysctl_consdev, 0, NULL, sizeof(dev_t), 232 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL); 233 } 234 235 /* 236 * These variables are needed by /sbin/savecore 237 */ 238 u_int32_t dumpmag = 0x8fca0101; /* magic number */ 239 int dumpsize = 0; /* pages */ 240 long dumplo = 0; /* blocks */ 241 242 /* 243 * This is called by main to set dumplo and dumpsize. 244 * Dumps always skip the first CLBYTES of disk space 245 * in case there might be a disk label stored there. 246 * If there is extra space, put dump at the end to 247 * reduce the chance that swapping trashes it. 248 */ 249 void 250 cpu_dumpconf(void) 251 { 252 int nblks; /* size of dump area */ 253 254 if (dumpdev == NODEV) 255 return; 256 nblks = bdev_size(dumpdev); 257 if (nblks <= ctod(1)) 258 return; 259 260 /* 261 * XXX include the final RAM page which is not included in physmem. 262 */ 263 dumpsize = physmem + 1; 264 265 /* Always skip the first CLBYTES, in case there is a label there. */ 266 if (dumplo < ctod(1)) 267 dumplo = ctod(1); 268 269 /* Put dump at end of partition, and make it fit. */ 270 if (dumpsize > dtoc(nblks - dumplo)) 271 dumpsize = dtoc(nblks - dumplo); 272 if (dumplo < nblks - ctod(dumpsize)) 273 dumplo = nblks - ctod(dumpsize); 274 } 275 276 /* 277 * Dump physical memory onto the dump device. Called by doadump() 278 * in locore.s or by cpu_reboot() here in machdep.c 279 */ 280 void 281 dumpsys(void) 282 { 283 const struct bdevsw *bdev; 284 daddr_t blkno; /* current block to write */ 285 /* dump routine */ 286 int (*dump)(dev_t, daddr_t, void *, size_t); 287 int pg; /* page being dumped */ 288 vm_offset_t maddr; /* PA being dumped */ 289 int error; /* error code from (*dump)() */ 290 291 /* Don't put dump messages in msgbuf. */ 292 msgbufmapped = 0; 293 294 /* Make sure dump device is valid. */ 295 if (dumpdev == NODEV) 296 return; 297 bdev = bdevsw_lookup(dumpdev); 298 if (bdev == NULL) 299 return; 300 if (dumpsize == 0) { 301 cpu_dumpconf(); 302 if (dumpsize == 0) 303 return; 304 } 305 if (dumplo < 0) 306 return; 307 dump = bdev->d_dump; 308 blkno = dumplo; 309 310 printf("\ndumping to dev %"PRIx64", offset %ld\n", dumpdev, dumplo); 311 312 printf("dump "); 313 maddr = lowram; 314 for (pg = 0; pg < dumpsize; pg++) { 315 #define NPGMB (1024*1024/PAGE_SIZE) 316 /* print out how many MBs we have dumped */ 317 if (pg && (pg % NPGMB) == 0) 318 printf("%d ", pg / NPGMB); 319 #undef NPGMB 320 pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr, 321 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED); 322 pmap_update(pmap_kernel()); 323 324 error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE); 325 switch (error) { 326 case 0: 327 maddr += PAGE_SIZE; 328 blkno += btodb(PAGE_SIZE); 329 break; 330 331 case ENXIO: 332 printf("device bad\n"); 333 return; 334 335 case EFAULT: 336 printf("device not ready\n"); 337 return; 338 339 case EINVAL: 340 printf("area improper\n"); 341 return; 342 343 case EIO: 344 printf("i/o error\n"); 345 return; 346 347 case EINTR: 348 printf("aborted from console\n"); 349 return; 350 351 default: 352 printf("error %d\n", error); 353 return; 354 } 355 } 356 printf("succeeded\n"); 357 } 358 359 #ifdef PANICBUTTON 360 /* 361 * Declare these so they can be patched. 362 */ 363 int panicbutton = 1; /* non-zero if panic buttons are enabled */ 364 int candbdiv = 2; /* give em half a second (hz / candbdiv) */ 365 366 void candbtimer(void *); 367 368 int crashandburn; 369 370 void 371 candbtimer(void *arg) 372 { 373 374 crashandburn = 0; 375 } 376 #endif /* PANICBUTTON */ 377 378 static int innmihand; /* simple mutex */ 379 380 /* 381 * Level 7 interrupts can be caused by the keyboard or parity errors. 382 */ 383 void 384 nmihand(struct frame frame) 385 { 386 387 /* Prevent unwanted recursion. */ 388 if (innmihand) 389 return; 390 innmihand = 1; 391 392 printf("NMI\n"); 393 #if defined(DDB) || defined(KGDB) 394 Debugger(); 395 #endif 396 397 innmihand = 0; 398 } 399