1 /* $NetBSD: machdep.c,v 1.122 2024/03/05 14:15:33 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1998 Darrin B. Jewell
5 * Copyright (c) 1988 University of Utah.
6 * Copyright (c) 1982, 1986, 1990, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * the Systems Programming Group of the University of Utah Computer
11 * Science Department.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * from: Utah $Hdr: machdep.c 1.74 92/12/20$
38 *
39 * @(#)machdep.c 8.10 (Berkeley) 4/20/94
40 */
41
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.122 2024/03/05 14:15:33 thorpej Exp $");
44
45 #include "opt_ddb.h"
46 #include "opt_kgdb.h"
47 #include "opt_modular.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/signalvar.h>
52 #include <sys/kernel.h>
53 #include <sys/proc.h>
54 #include <sys/buf.h>
55 #include <sys/reboot.h>
56 #include <sys/conf.h>
57 #include <sys/file.h>
58 #include <sys/device.h>
59 #include <sys/mbuf.h>
60 #include <sys/msgbuf.h>
61 #include <sys/ioctl.h>
62 #include <sys/tty.h>
63 #include <sys/mount.h>
64 #include <sys/exec.h>
65 #include <sys/exec_aout.h> /* for MID_* */
66 #include <sys/core.h>
67 #include <sys/kcore.h>
68 #include <sys/vnode.h>
69 #include <sys/syscallargs.h>
70 #include <sys/ksyms.h>
71 #include <sys/module.h>
72 #ifdef KGDB
73 #include <sys/kgdb.h>
74 #endif
75 #include <sys/boot_flag.h>
76 #include <sys/cpu.h>
77
78 #include <uvm/uvm_extern.h>
79
80 #ifdef DDB
81 #include <machine/db_machdep.h>
82 #include <ddb/db_access.h>
83 #include <ddb/db_sym.h>
84 #include <ddb/db_extern.h>
85 #endif
86
87 #ifdef KGDB
88 /* Is zs configured in? */
89 #include "zsc.h"
90 #if (NZSC > 0)
91 #include <next68k/dev/zs_cons.h>
92 #endif
93 #endif
94
95 #include <sys/sysctl.h>
96
97 #include <machine/cpu.h>
98 #include <machine/bus.h>
99 #include <machine/reg.h>
100 #include <machine/pcb.h>
101 #include <machine/psl.h>
102 #include <machine/pte.h>
103 #include <machine/vmparam.h>
104 #include <dev/cons.h>
105
106 #include <machine/kcore.h> /* XXX should be pulled in by sys/kcore.h */
107
108 #include <next68k/next68k/isr.h>
109 #include <next68k/next68k/nextrom.h>
110 #include <next68k/next68k/rtc.h>
111 #include <next68k/next68k/seglist.h>
112
113 #include <dev/mm.h>
114
115 #include "ksyms.h"
116
117 int nsym;
118 char *ssym;
119 extern char *esym;
120
121 #define MAXMEM 64*1024 /* XXX - from cmap.h */
122
123 /* the following is used externally (sysctl_hw) */
124 char machine[] = MACHINE; /* from <machine/param.h> */
125
126 /* Our exported CPU info; we can have only one. */
127 struct cpu_info cpu_info_store;
128
129 struct vm_map *phys_map = NULL;
130
131 paddr_t msgbufpa; /* PA of message buffer */
132
133 int maxmem; /* max memory per process */
134
135 extern u_int lowram;
136 extern short exframesize[];
137
138 /* prototypes for local functions */
139 void identifycpu(void);
140 void initcpu(void);
141 void dumpsys(void);
142
143 int cpu_dumpsize(void);
144 int cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
145 void cpu_init_kcore_hdr(void);
146
147 /* functions called from locore.s */
148 void next68k_init(void);
149 void straytrap(int, u_short);
150
151 /*
152 * Machine-independent crash dump header info.
153 */
154 cpu_kcore_hdr_t cpu_kcore_hdr;
155
156 /*
157 * Memory segments initialized in locore, which are eventually loaded
158 * as managed VM pages.
159 */
160 phys_seg_list_t phys_seg_list[VM_PHYSSEG_MAX];
161
162 /*
163 * Memory segments to dump. This is initialized from the phys_seg_list
164 * before pages are stolen from it for VM system overhead. I.e. this
165 * covers the entire range of physical memory.
166 */
167 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
168 int mem_cluster_cnt;
169
170 /*
171 * On the 68020/68030, the value of delay_divisor is roughly
172 * 2048 / cpuspeed (where cpuspeed is in MHz).
173 *
174 * On the 68040/68060(?), the value of delay_divisor is roughly
175 * 759 / cpuspeed (where cpuspeed is in MHz).
176 * XXX -- is the above formula correct?
177 */
178 int cpuspeed = 33; /* relative cpu speed; XXX skewed on 68040 */
179 int delay_divisor = 759 / 33; /* delay constant; assume fastest 33 MHz */
180
181 /****************************************************************/
182
183 /*
184 * Early initialization, before main() is called.
185 */
186 void
next68k_init(void)187 next68k_init(void)
188 {
189 int i;
190
191 /*
192 * Tell the VM system about available physical memory.
193 */
194 for (i = 0; i < mem_cluster_cnt; i++) {
195 if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) {
196 /*
197 * Segment has been completely gobbled up.
198 */
199 continue;
200 }
201 /*
202 * Note the index of the mem cluster is the free
203 * list we want to put the memory on.
204 */
205 uvm_page_physload(atop(phys_seg_list[i].ps_start),
206 atop(phys_seg_list[i].ps_end),
207 atop(phys_seg_list[i].ps_start),
208 atop(phys_seg_list[i].ps_end),
209 VM_FREELIST_DEFAULT);
210 }
211
212 {
213 char *p = rom_boot_arg;
214 boothowto = 0;
215 if (*p++ == '-') {
216 for (;*p;p++)
217 BOOT_FLAG(*p, boothowto);
218 }
219 }
220
221 /*
222 * Initialize error message buffer (at end of core).
223 */
224 for (i = 0; i < btoc(round_page(MSGBUFSIZE)); i++)
225 pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE,
226 msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE,
227 VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
228 initmsgbuf(msgbufaddr, round_page(MSGBUFSIZE));
229 pmap_update(pmap_kernel());
230 }
231
232 /*
233 * Console initialization: called early on from main,
234 * before vm init or startup. Do enough configuration
235 * to choose and initialize a console.
236 */
237 void
consinit(void)238 consinit(void)
239 {
240 static int init = 0;
241
242 /*
243 * Generic console: sys/dev/cons.c
244 * Initializes either ite or ser as console.
245 * Can be called from locore.s and init_main.c.
246 */
247
248 if (!init) {
249 cninit();
250 #if defined(KGDB) && (NZSC > 0)
251 zs_kgdb_init();
252 #endif
253 #if NKSYMS || defined(DDB) || defined(MODULAR)
254 /* Initialize kernel symbol table, if compiled in. */
255 ksyms_addsyms_elf(nsym, ssym, esym);
256 #endif
257 if (boothowto & RB_KDB) {
258 #if defined(KGDB)
259 kgdb_connect(1);
260 #elif defined(DDB)
261 Debugger();
262 #endif
263 }
264
265 init = 1;
266 }
267 }
268
269 /*
270 * cpu_startup: allocate memory for variable-sized tables,
271 * initialize CPU, and do autoconfiguration.
272 */
273 void
cpu_startup(void)274 cpu_startup(void)
275 {
276 vaddr_t minaddr, maxaddr;
277 char pbuf[9];
278 #ifdef DEBUG
279 extern int pmapdebug;
280 int opmapdebug = pmapdebug;
281
282 pmapdebug = 0;
283 #endif
284
285 if (fputype != FPU_NONE)
286 m68k_make_fpu_idle_frame();
287
288 /*
289 * Initialize the kernel crash dump header.
290 */
291 cpu_init_kcore_hdr();
292
293 /*
294 * Good {morning,afternoon,evening,night}.
295 */
296 printf("%s%s", copyright, version);
297 identifycpu();
298 format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
299 printf("total memory = %s\n", pbuf);
300
301 minaddr = 0;
302 /*
303 * Allocate a submap for physio
304 */
305 phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
306 VM_PHYS_SIZE, 0, false, NULL);
307
308 #ifdef DEBUG
309 pmapdebug = opmapdebug;
310 #endif
311 format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
312 printf("avail memory = %s\n", pbuf);
313
314 /*
315 * Set up CPU-specific registers, cache, etc.
316 */
317 initcpu();
318 }
319
320 void
identifycpu(void)321 identifycpu(void)
322 {
323 const char *cpu_str, *mmu_str, *fpu_str, *cache_str;
324 extern int turbo;
325
326 /*
327 * ...and the CPU type.
328 */
329 switch (cputype) {
330 case CPU_68040:
331 cpu_str = "MC68040";
332 cpuspeed = turbo ? 33 : 25;
333 delay_divisor = 759 / cpuspeed;
334 break;
335 case CPU_68030:
336 cpu_str = "MC68030";
337 cpuspeed = 25;
338 delay_divisor = 2048 / cpuspeed;
339 break;
340 #if 0
341 case CPU_68020:
342 cpu_str = "MC68020";
343 break;
344 #endif
345 default:
346 printf("\nunknown cputype %d\n", cputype);
347 panic("startup");
348 }
349
350 /*
351 * ...and the MMU type.
352 */
353 switch (mmutype) {
354 case MMU_68040:
355 case MMU_68030:
356 mmu_str = "+MMU";
357 break;
358 #if 0
359 case MMU_68851:
360 mmu_str = ", MC68851 MMU";
361 break;
362 #endif
363 default:
364 printf("%s: unknown MMU type %d\n", cpu_str, mmutype);
365 panic("startup");
366 }
367
368 /*
369 * ...and the FPU type.
370 */
371 switch (fputype) {
372 case FPU_68040:
373 fpu_str = "+FPU";
374 break;
375 case FPU_68882:
376 fpu_str = ", MC68882 FPU";
377 break;
378 case FPU_68881:
379 fpu_str = ", MC68881 FPU";
380 break;
381 default:
382 fpu_str = ", unknown FPU";
383 }
384
385 /*
386 * ...and finally, the cache type.
387 */
388 if (cputype == CPU_68040)
389 cache_str = ", 4k on-chip physical I/D caches";
390 else
391 cache_str = "";
392
393 cpu_setmodel("NeXT/%s CPU%s%s%s", cpu_str, mmu_str, fpu_str, cache_str);
394 printf("%s\n", cpu_getmodel());
395 }
396
397 /*
398 * machine dependent system variables.
399 */
400 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
401 {
402
403 sysctl_createv(clog, 0, NULL, NULL,
404 CTLFLAG_PERMANENT,
405 CTLTYPE_NODE, "machdep", NULL,
406 NULL, 0, NULL, 0,
407 CTL_MACHDEP, CTL_EOL);
408
409 #if 0
410 sysctl_createv(clog, 0, NULL, NULL,
411 CTLFLAG_PERMANENT,
412 CTLTYPE_STRUCT, "console_device", NULL,
413 sysctl_consdev, 0, NULL, sizeof(dev_t),
414 CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
415 #endif
416 }
417
418 /* See: sig_machdep.c */
419
420 int waittime = -1;
421
422 void
cpu_reboot(int howto,char * bootstr)423 cpu_reboot(int howto, char *bootstr)
424 {
425 struct pcb *pcb = lwp_getpcb(curlwp);
426
427 /* take a snap shot before clobbering any registers */
428 if (pcb != NULL)
429 savectx(pcb);
430
431 /* If system is cold, just halt. */
432 if (cold) {
433 howto |= RB_HALT;
434 goto haltsys;
435 }
436
437 boothowto = howto;
438 if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
439 waittime = 0;
440 vfs_shutdown();
441 }
442
443 /* Disable interrupts. */
444 splhigh();
445
446 /* If rebooting and a dump is requested, do it. */
447 if (howto & RB_DUMP)
448 dumpsys();
449
450 haltsys:
451 /* Run any shutdown hooks. */
452 doshutdownhooks();
453
454 pmf_system_shutdown(boothowto);
455
456 #if defined(PANICWAIT) && !defined(DDB)
457 if ((howto & RB_HALT) == 0 && panicstr) {
458 printf("hit any key to reboot...\n");
459 cnpollc(1);
460 (void)cngetc();
461 cnpollc(0);
462 printf("\n");
463 }
464 #endif
465
466 if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
467 poweroff();
468 }
469
470 /* Finally, halt/reboot the system. */
471 if (howto & RB_HALT) {
472 monbootflag = 0x2d680000; /* "-h" */
473 }
474
475 printf("rebooting...\n");
476 DELAY(1000000);
477 doboot();
478 /*NOTREACHED*/
479 }
480
481 /*
482 * Initialize the kernel crash dump header.
483 */
484 void
cpu_init_kcore_hdr(void)485 cpu_init_kcore_hdr(void)
486 {
487 cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
488 struct m68k_kcore_hdr *m = &h->un._m68k;
489 int i;
490 extern char end[];
491
492 memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
493
494 /*
495 * Initialize the `dispatcher' portion of the header.
496 */
497 strcpy(h->name, machine);
498 h->page_size = PAGE_SIZE;
499 h->kernbase = KERNBASE;
500
501 /*
502 * Fill in information about our MMU configuration.
503 */
504 m->mmutype = mmutype;
505 m->sg_v = SG_V;
506 m->sg_frame = SG_FRAME;
507 m->sg_ishift = SG_ISHIFT;
508 m->sg_pmask = SG_PMASK;
509 m->sg40_shift1 = SG4_SHIFT1;
510 m->sg40_mask2 = SG4_MASK2;
511 m->sg40_shift2 = SG4_SHIFT2;
512 m->sg40_mask3 = SG4_MASK3;
513 m->sg40_shift3 = SG4_SHIFT3;
514 m->sg40_addr1 = SG4_ADDR1;
515 m->sg40_addr2 = SG4_ADDR2;
516 m->pg_v = PG_V;
517 m->pg_frame = PG_FRAME;
518
519 /*
520 * Initialize pointer to kernel segment table.
521 */
522 m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
523
524 /*
525 * Initialize relocation value such that:
526 *
527 * pa = (va - KERNBASE) + reloc
528 */
529 m->reloc = lowram;
530
531 /*
532 * Define the end of the relocatable range.
533 */
534 m->relocend = (uint32_t)end;
535
536 /*
537 * The next68k has multiple memory segments.
538 */
539 for (i = 0; i < mem_cluster_cnt; i++) {
540 m->ram_segs[i].start = mem_clusters[i].start;
541 m->ram_segs[i].size = mem_clusters[i].size;
542 }
543 }
544
545 /*
546 * Compute the size of the machine-dependent crash dump header.
547 * Returns size in disk blocks.
548 */
549
550 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
551 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
552
553 int
cpu_dumpsize(void)554 cpu_dumpsize(void)
555 {
556
557 return btodb(MDHDRSIZE);
558 }
559
560 /*
561 * Called by dumpsys() to dump the machine-dependent header.
562 */
563 int
cpu_dump(int (* dump)(dev_t,daddr_t,void *,size_t),daddr_t * blknop)564 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
565 {
566 int buf[MDHDRSIZE / sizeof(int)];
567 cpu_kcore_hdr_t *chdr;
568 kcore_seg_t *kseg;
569 int error;
570
571 kseg = (kcore_seg_t *)buf;
572 chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
573 sizeof(int)];
574
575 /* Create the segment header. */
576 CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
577 kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
578
579 memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
580 error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
581 *blknop += btodb(sizeof(buf));
582 return (error);
583 }
584
585 /*
586 * These variables are needed by /sbin/savecore
587 */
588 uint32_t dumpmag = 0x8fca0101; /* magic number */
589 int dumpsize = 0; /* pages */
590 long dumplo = 0; /* blocks */
591
592 /*
593 * This is called by main to set dumplo and dumpsize.
594 * Dumps always skip the first PAGE_SIZE of disk space
595 * in case there might be a disk label stored there.
596 * If there is extra space, put dump at the end to
597 * reduce the chance that swapping trashes it.
598 */
599 void
cpu_dumpconf(void)600 cpu_dumpconf(void)
601 {
602 int chdrsize; /* size of dump header */
603 int nblks; /* size of dump area */
604
605 if (dumpdev == NODEV)
606 return;
607 nblks = bdev_size(dumpdev);
608 chdrsize = cpu_dumpsize();
609
610 dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
611
612 /*
613 * Check do see if we will fit. Note we always skip the
614 * first PAGE_SIZE in case there is a disk label there.
615 */
616 if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
617 dumpsize = 0;
618 dumplo = -1;
619 return;
620 }
621
622 /*
623 * Put dump at the end of the partition.
624 */
625 dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
626 }
627
628 /*
629 * Dump physical memory onto the dump device. Called by cpu_reboot().
630 */
631 void
dumpsys(void)632 dumpsys(void)
633 {
634 const struct bdevsw *bdev;
635 daddr_t blkno; /* current block to write */
636 /* dump routine */
637 int (*dump)(dev_t, daddr_t, void *, size_t);
638 int pg; /* page being dumped */
639 vm_offset_t maddr; /* PA being dumped */
640 int error; /* error code from (*dump)() */
641
642 /* XXX initialized here because of gcc lossage */
643 maddr = lowram;
644 pg = 0;
645
646 /* Don't put dump messages in msgbuf. */
647 msgbufmapped = 0;
648
649 /* Make sure dump device is valid. */
650 if (dumpdev == NODEV)
651 return;
652 bdev = bdevsw_lookup(dumpdev);
653 if (bdev == NULL)
654 return;
655 if (dumpsize == 0) {
656 cpu_dumpconf();
657 if (dumpsize == 0)
658 return;
659 }
660 if (dumplo < 0)
661 return;
662 dump = bdev->d_dump;
663 blkno = dumplo;
664
665 printf("\ndumping to dev 0x%"PRIx64", offset %ld\n", dumpdev, dumplo);
666
667 printf("dump ");
668
669 /* Write the dump header. */
670 error = cpu_dump(dump, &blkno);
671 if (error)
672 goto bad;
673
674 for (pg = 0; pg < dumpsize; pg++) {
675 #define NPGMB (1024*1024/PAGE_SIZE)
676 /* print out how many MBs we have dumped */
677 if (pg && (pg % NPGMB) == 0)
678 printf_nolog("%d ", pg / NPGMB);
679 #undef NPGMB
680 pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
681 VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
682 pmap_update(pmap_kernel());
683
684 error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
685 bad:
686 switch (error) {
687 case 0:
688 maddr += PAGE_SIZE;
689 blkno += btodb(PAGE_SIZE);
690 break;
691
692 case ENXIO:
693 printf("device bad\n");
694 return;
695
696 case EFAULT:
697 printf("device not ready\n");
698 return;
699
700 case EINVAL:
701 printf("area improper\n");
702 return;
703
704 case EIO:
705 printf("i/o error\n");
706 return;
707
708 case EINTR:
709 printf("aborted from console\n");
710 return;
711
712 default:
713 printf("error %d\n", error);
714 return;
715 }
716 }
717 printf("succeeded\n");
718 }
719
720 void
initcpu(void)721 initcpu(void)
722 {
723 }
724
725 void
straytrap(int pc,u_short evec)726 straytrap(int pc, u_short evec)
727 {
728 printf("unexpected trap (vector offset %x) from %x\n",
729 evec & 0xFFF, pc);
730
731 /* XXX kgdb/ddb entry? */
732 }
733
734 /* XXX should change the interface, and make one badaddr() function */
735
736 int *nofault;
737
738 #if 0
739 int
740 badaddr(void *addr, int nbytes)
741 {
742 int i;
743 label_t faultbuf;
744
745 #ifdef lint
746 i = *addr; if (i) return (0);
747 #endif
748
749 nofault = (int *) &faultbuf;
750 if (setjmp((label_t *)nofault)) {
751 nofault = (int *) 0;
752 return(1);
753 }
754
755 switch (nbytes) {
756 case 1:
757 i = *(volatile char *)addr;
758 break;
759
760 case 2:
761 i = *(volatile short *)addr;
762 break;
763
764 case 4:
765 i = *(volatile int *)addr;
766 break;
767
768 default:
769 panic("badaddr: bad request");
770 }
771 nofault = NULL;
772 return (0);
773 }
774 #endif
775
776 /*
777 * Level 7 interrupts can be caused by the keyboard or parity errors.
778 */
779 int
nmihand(void * frame)780 nmihand(void *frame)
781 {
782 static int innmihand; /* simple mutex */
783
784 /* Prevent unwanted recursion. */
785 if (innmihand)
786 return 0;
787 innmihand = 1;
788
789 printf("Got a NMI");
790
791 if (!INTR_OCCURRED(NEXT_I_NMI)) {
792 printf("But NMI isn't set in intrstat!\n");
793 }
794 INTR_DISABLE(NEXT_I_NMI);
795
796 #if defined(DDB)
797 printf(": entering debugger\n");
798 Debugger();
799 printf("continuing after NMI\n");
800 #elif defined(KGDB)
801 kgdb_connect(1);
802 #else
803 printf(": ignoring\n");
804 #endif /* DDB */
805
806 INTR_ENABLE(NEXT_I_NMI);
807
808 innmihand = 0;
809
810 return 0;
811 }
812
813
814 /*
815 * cpu_exec_aout_makecmds():
816 * CPU-dependent a.out format hook for execve().
817 *
818 * Determine of the given exec package refers to something which we
819 * understand and, if so, set up the vmcmds for it.
820 */
821 int
cpu_exec_aout_makecmds(struct lwp * l,struct exec_package * epp)822 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
823 {
824 return ENOEXEC;
825 }
826
827 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)828 mm_md_physacc(paddr_t pa, vm_prot_t prot)
829 {
830
831 return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0;
832 }
833
834 #ifdef MODULAR
835 /*
836 * Push any modules loaded by the bootloader etc.
837 */
838 void
module_init_md(void)839 module_init_md(void)
840 {
841 }
842 #endif
843