Annotation of src/sys/arch/amiga/amiga/machdep.c, Revision 1.96
1.96 ! mycroft 1: /* $NetBSD: machdep.c,v 1.95 1997/08/27 18:31:17 is Exp $ */
1.40 cgd 2:
1.1 mw 3: /*
4: * Copyright (c) 1988 University of Utah.
5: * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
6: * 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. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the University of
23: * California, Berkeley and its contributors.
24: * 4. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
1.4 mw 40: * from: Utah $Hdr: machdep.c 1.63 91/04/24$
41: *
42: * @(#)machdep.c 7.16 (Berkeley) 6/3/91
1.1 mw 43: */
44:
1.9 chopps 45: #include <sys/param.h>
46: #include <sys/systm.h>
47: #include <sys/signalvar.h>
48: #include <sys/kernel.h>
49: #include <sys/map.h>
50: #include <sys/proc.h>
51: #include <sys/buf.h>
52: #include <sys/reboot.h>
53: #include <sys/conf.h>
54: #include <sys/file.h>
55: #include <sys/clist.h>
56: #include <sys/callout.h>
57: #include <sys/malloc.h>
58: #include <sys/mbuf.h>
59: #include <sys/msgbuf.h>
1.5 mw 60: #include <sys/user.h>
61: #include <sys/exec.h> /* for PS_STRINGS */
1.23 chopps 62: #include <sys/vnode.h>
63: #include <sys/queue.h>
64: #include <sys/sysctl.h>
1.39 cgd 65: #include <sys/mount.h>
66: #include <sys/syscallargs.h>
1.68 mhitch 67: #include <sys/core.h>
68: #include <sys/kcore.h>
1.1 mw 69: #ifdef SYSVSHM
1.5 mw 70: #include <sys/shm.h>
71: #endif
72: #ifdef SYSVMSG
73: #include <sys/msg.h>
74: #endif
75: #ifdef SYSVSEM
76: #include <sys/sem.h>
1.1 mw 77: #endif
1.9 chopps 78: #include <net/netisr.h>
1.1 mw 79: #define MAXMEM 64*1024*CLSIZE /* XXX - from cmap.h */
1.9 chopps 80: #include <vm/vm_param.h>
81: #include <vm/pmap.h>
82: #include <vm/vm_map.h>
83: #include <vm/vm_object.h>
84: #include <vm/vm_kern.h>
85: #include <vm/vm_page.h>
1.61 veego 86:
87: #include <machine/db_machdep.h>
88: #include <ddb/db_sym.h>
89: #include <ddb/db_extern.h>
90:
1.23 chopps 91: #include <machine/cpu.h>
92: #include <machine/reg.h>
93: #include <machine/psl.h>
94: #include <machine/pte.h>
1.68 mhitch 95: #include <machine/kcore.h>
1.23 chopps 96: #include <dev/cons.h>
97: #include <amiga/amiga/isr.h>
1.9 chopps 98: #include <amiga/amiga/custom.h>
1.66 is 99: #ifdef DRACO
100: #include <amiga/amiga/drcustom.h>
101: #endif
1.9 chopps 102: #include <amiga/amiga/cia.h>
103: #include <amiga/amiga/cc.h>
104: #include <amiga/amiga/memlist.h>
1.45 chopps 105:
1.17 chopps 106: #include "fd.h"
1.22 chopps 107: #include "ser.h"
1.84 is 108: #include "arp.h"
1.61 veego 109: #include "ppp.h"
110:
111: #include <net/netisr.h>
112: #include <net/if.h>
113:
114: #ifdef INET
115: #include <netinet/in.h>
1.87 is 116: #if NARP > 0
1.83 is 117: #include <netinet/if_inarp.h>
1.61 veego 118: #endif
119: #include <netinet/ip_var.h>
120: #endif
121: #ifdef NS
122: #include <netns/ns_var.h>
123: #endif
124: #ifdef ISO
125: #include <netiso/iso.h>
126: #include <netiso/clnp.h>
127: #endif
1.88 christos 128: #ifdef NETATALK
129: #include <netatalk/at_extern.h>
130: #endif
1.61 veego 131: #if NPPP > 0
132: #include <net/ppp_defs.h>
133: #include <net/if_ppp.h>
134: #endif
1.1 mw 135:
1.53 paulus 136:
1.1 mw 137: /* vm_map_t buffer_map; */
138: extern vm_offset_t avail_end;
1.42 chopps 139: extern vm_offset_t avail_start;
1.1 mw 140:
1.61 veego 141: /* prototypes */
142: void identifycpu __P((void));
143: vm_offset_t reserve_dumppages __P((vm_offset_t));
144: void dumpsys __P((void));
145: void initcpu __P((void));
146: void straytrap __P((int, u_short));
147: static void netintr __P((void));
148: static void call_sicallbacks __P((void));
1.95 is 149: static void _softintr_callit __P((void *, void *));
1.61 veego 150: void intrhand __P((int));
1.64 mhitch 151: #if NSER > 0
152: void ser_outintr __P((void));
153: #endif
154: #if NFD > 0
155: void fdintr __P((int));
156: #endif
1.61 veego 157:
1.1 mw 158: /*
1.81 is 159: * patched by some devices at attach time (currently, only drcom)
160: */
161: u_int16_t amiga_ttyspl = PSL_S|PSL_IPL4;
162:
163: /*
1.1 mw 164: * Declare these as initialized data so we can patch them.
165: */
166: int nswbuf = 0;
167: #ifdef NBUF
168: int nbuf = NBUF;
169: #else
170: int nbuf = 0;
171: #endif
172: #ifdef BUFPAGES
173: int bufpages = BUFPAGES;
174: #else
175: int bufpages = 0;
176: #endif
177: int msgbufmapped; /* set when safe to use msgbuf */
178: int maxmem; /* max memory per process */
179: int physmem = MAXMEM; /* max supported memory, changes to actual */
180: /*
1.45 chopps 181: * extender "register" for software interrupts. Moved here
182: * from locore.s, since softints are no longer dealt with
183: * in locore.s.
184: */
185: unsigned char ssir;
186: /*
1.1 mw 187: * safepri is a safe priority for sleep to set for a spin-wait
188: * during autoconfiguration or after a panic.
189: */
190: int safepri = PSL_LOWIPL;
191: extern int freebufspace;
192: extern u_int lowram;
193:
194: /* used in init_main.c */
1.91 veego 195: char *cpu_type = "m68k";
1.23 chopps 196: /* the following is used externally (sysctl_hw) */
1.91 veego 197: char machine[] = MACHINE; /* from <machine/param.h> */
1.23 chopps 198:
1.5 mw 199: /*
1.1 mw 200: * Console initialization: called early on from main,
201: * before vm init or startup. Do enough configuration
202: * to choose and initialize a console.
203: */
204: void
205: consinit()
206: {
1.5 mw 207: /* initialize custom chip interface */
1.66 is 208: #ifdef DRACO
209: if (is_draco()) {
210: /* XXX to be done */
211: } else
212: #endif
213: custom_chips_init();
1.1 mw 214: /*
215: * Initialize the console before we print anything out.
216: */
217: cninit();
1.11 chopps 218:
219: #if defined (DDB)
220: ddb_init();
221: if (boothowto & RB_KDB)
222: Debugger();
223: #endif
1.1 mw 224: }
225:
226: /*
227: * cpu_startup: allocate memory for variable-sized tables,
228: * initialize cpu, and do autoconfiguration.
229: */
230: void
231: cpu_startup()
232: {
233: register unsigned i;
234: register caddr_t v, firstaddr;
235: int base, residual;
236: #ifdef DEBUG
237: extern int pmapdebug;
238: int opmapdebug = pmapdebug;
239: #endif
240: vm_offset_t minaddr, maxaddr;
1.61 veego 241: vm_size_t size = 0;
1.62 veego 242: #if defined(MACHINE_NONCONTIG) && defined(DEBUG)
1.42 chopps 243: extern struct {
244: vm_offset_t start;
245: vm_offset_t end;
246: int first_page;
247: } phys_segs[16];
248: #endif
1.1 mw 249:
250: /*
251: * Initialize error message buffer (at end of core).
252: */
253: #ifdef DEBUG
254: pmapdebug = 0;
255: #endif
256: /* avail_end was pre-decremented in pmap_bootstrap to compensate */
257: for (i = 0; i < btoc(sizeof (struct msgbuf)); i++)
1.46 mycroft 258: pmap_enter(pmap_kernel(), (vm_offset_t)msgbufp,
1.27 chopps 259: avail_end + i * NBPG, VM_PROT_ALL, TRUE);
1.1 mw 260: msgbufmapped = 1;
261:
262: /*
263: * Good {morning,afternoon,evening,night}.
264: */
1.80 christos 265: printf(version);
1.1 mw 266: identifycpu();
1.80 christos 267: printf("real mem = %d (%d pages)\n", ctob(physmem), ctob(physmem)/NBPG);
1.1 mw 268:
269: /*
270: * Allocate space for system data structures.
271: * The first available real memory address is in "firstaddr".
272: * The first available kernel virtual address is in "v".
273: * As pages of kernel virtual memory are allocated, "v" is incremented.
274: * As pages of memory are allocated and cleared,
275: * "firstaddr" is incremented.
276: * An index into the kernel page table corresponding to the
277: * virtual memory address maintained in "v" is kept in "mapaddr".
278: */
279: /*
280: * Make two passes. The first pass calculates how much memory is
281: * needed and allocates it. The second pass assigns virtual
282: * addresses to the various data structures.
283: */
284: firstaddr = 0;
285: again:
286: v = (caddr_t)firstaddr;
287:
288: #define valloc(name, type, num) \
289: (name) = (type *)v; v = (caddr_t)((name)+(num))
290: #define valloclim(name, type, num, lim) \
291: (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
292: /* valloc(cfree, struct cblock, nclist); */
293: valloc(callout, struct callout, ncallout);
294: #ifdef SYSVSHM
295: valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
296: #endif
1.5 mw 297: #ifdef SYSVSEM
298: valloc(sema, struct semid_ds, seminfo.semmni);
299: valloc(sem, struct sem, seminfo.semmns);
300: /* This is pretty disgusting! */
301: valloc(semu, int, (seminfo.semmnu * seminfo.semusz) / sizeof(int));
302: #endif
303: #ifdef SYSVMSG
304: valloc(msgpool, char, msginfo.msgmax);
305: valloc(msgmaps, struct msgmap, msginfo.msgseg);
306: valloc(msghdrs, struct msg, msginfo.msgtql);
307: valloc(msqids, struct msqid_ds, msginfo.msgmni);
308: #endif
1.1 mw 309: /*
1.37 chopps 310: * Determine how many buffers to allocate. We allocate
311: * the BSD standard of use 10% of memory for the first 2 Meg,
312: * 5% of remaining. Insure a minimum of 16 buffers.
313: * We allocate 3/4 as many swap buffer headers as file i/o buffers.
1.1 mw 314: */
1.5 mw 315: if (bufpages == 0)
316: if (physmem < btoc(2 * 1024 * 1024))
317: bufpages = physmem / (10 * CLSIZE);
318: else
319: bufpages = (btoc(2 * 1024 * 1024) + physmem) /
320: (20 * CLSIZE);
321:
1.1 mw 322: if (nbuf == 0) {
323: nbuf = bufpages;
324: if (nbuf < 16)
325: nbuf = 16;
326: }
1.4 mw 327:
1.1 mw 328: if (nswbuf == 0) {
1.37 chopps 329: nswbuf = (nbuf * 3 / 4) &~ 1; /* force even */
1.1 mw 330: if (nswbuf > 256)
331: nswbuf = 256; /* sanity */
332: }
333: valloc(swbuf, struct buf, nswbuf);
334: valloc(buf, struct buf, nbuf);
335: /*
336: * End of first pass, size has been calculated so allocate memory
337: */
338: if (firstaddr == 0) {
339: size = (vm_size_t)(v - firstaddr);
340: firstaddr = (caddr_t) kmem_alloc(kernel_map, round_page(size));
341: if (firstaddr == 0)
342: panic("startup: no room for tables");
343: goto again;
344: }
345: /*
346: * End of second pass, addresses have been assigned
347: */
348: if ((vm_size_t)(v - firstaddr) != size)
349: panic("startup: table size inconsistency");
350:
351: /*
352: * Now allocate buffers proper. They are different than the above
353: * in that they usually occupy more virtual memory than physical.
354: */
355: size = MAXBSIZE * nbuf;
1.5 mw 356: buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
1.27 chopps 357: &maxaddr, size, TRUE);
1.1 mw 358: minaddr = (vm_offset_t)buffers;
359: if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
360: &minaddr, size, FALSE) != KERN_SUCCESS)
361: panic("startup: cannot allocate buffers");
1.4 mw 362: if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
363: /* don't want to alloc more physical mem than needed */
364: bufpages = btoc(MAXBSIZE) * nbuf;
365: }
1.1 mw 366: base = bufpages / nbuf;
367: residual = bufpages % nbuf;
368: for (i = 0; i < nbuf; i++) {
369: vm_size_t curbufsize;
370: vm_offset_t curbuf;
371:
372: /*
373: * First <residual> buffers get (base+1) physical pages
374: * allocated for them. The rest get (base) physical pages.
375: *
376: * The rest of each buffer occupies virtual space,
377: * but has no physical memory allocated for it.
378: */
379: curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
380: curbufsize = CLBYTES * (i < residual ? base+1 : base);
381: vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
382: vm_map_simplify(buffer_map, curbuf);
383: }
384:
385: /*
386: * Allocate a submap for exec arguments. This map effectively
387: * limits the number of processes exec'ing at any time.
388: */
389: exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
390: 16*NCARGS, TRUE);
391:
392: /*
393: * Allocate a submap for physio
394: */
395: phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
396: VM_PHYS_SIZE, TRUE);
397:
398: /*
1.86 thorpej 399: * Finally, allocate mbuf cluster submap.
1.1 mw 400: */
1.5 mw 401: mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
1.1 mw 402: VM_MBUF_SIZE, FALSE);
403:
404: /*
405: * Initialize callouts
406: */
407: callfree = callout;
408: for (i = 1; i < ncallout; i++)
409: callout[i-1].c_next = &callout[i];
410:
411: #ifdef DEBUG
412: pmapdebug = opmapdebug;
413: #endif
1.80 christos 414: printf("avail mem = %ld (%ld pages)\n", ptoa(cnt.v_free_count),
1.18 chopps 415: ptoa(cnt.v_free_count)/NBPG);
1.80 christos 416: printf("using %d buffers containing %d bytes of memory\n",
1.79 christos 417: nbuf, bufpages * CLBYTES);
1.22 chopps 418:
1.29 chopps 419: /*
420: * display memory configuration passed from loadbsd
421: */
422: if (memlist->m_nseg > 0 && memlist->m_nseg < 16)
423: for (i = 0; i < memlist->m_nseg; i++)
1.80 christos 424: printf("memory segment %d at %x size %x\n", i,
1.29 chopps 425: memlist->m_seg[i].ms_start,
426: memlist->m_seg[i].ms_size);
1.42 chopps 427: #if defined(MACHINE_NONCONTIG) && defined(DEBUG)
1.80 christos 428: printf("Physical memory segments:\n");
1.66 is 429: for (i = 0; i < memlist->m_nseg && phys_segs[i].start; ++i)
1.80 christos 430: printf("Physical segment %d at %08lx size %ld offset %d\n", i,
1.42 chopps 431: phys_segs[i].start,
432: (phys_segs[i].end - phys_segs[i].start) / NBPG,
433: phys_segs[i].first_page);
434: #endif
1.66 is 435:
1.78 thorpej 436: #ifdef DEBUG_KERNEL_START
1.80 christos 437: printf("calling initcpu...\n");
1.66 is 438: #endif
1.1 mw 439: /*
440: * Set up CPU-specific registers, cache, etc.
441: */
442: initcpu();
443:
1.73 is 444: #ifdef DEBUG_KERNEL_START
1.80 christos 445: printf("survived initcpu...\n");
1.66 is 446: #endif
1.81 is 447:
1.1 mw 448: /*
449: * Set up buffers, so they can be used to read disk labels.
450: */
451: bufinit();
452:
1.73 is 453: #ifdef DEBUG_KERNEL_START
1.80 christos 454: printf("survived bufinit...\n");
1.66 is 455: #endif
1.1 mw 456: /*
457: * Configure the system.
458: */
459: configure();
1.73 is 460: #ifdef DEBUG_KERNEL_START
1.80 christos 461: printf("survived configure...\n");
1.66 is 462: #endif
1.1 mw 463: }
464:
465: /*
466: * Set registers on exec.
467: * XXX Should clear registers except sp, pc,
468: * but would break init; should be fixed soon.
469: */
470: void
1.96 ! mycroft 471: setregs(p, pack, stack)
1.1 mw 472: register struct proc *p;
1.48 christos 473: struct exec_package *pack;
1.1 mw 474: u_long stack;
475: {
1.27 chopps 476: struct frame *frame = (struct frame *)p->p_md.md_regs;
477:
1.48 christos 478: frame->f_pc = pack->ep_entry & ~1;
1.27 chopps 479: frame->f_regs[SP] = stack;
1.52 chopps 480: frame->f_regs[A2] = (int)PS_STRINGS;
1.27 chopps 481:
1.1 mw 482: #ifdef FPCOPROC
483: /* restore a null state frame */
484: p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
1.94 is 485: #ifdef FPU_EMULATE
486: if (!fputype)
487: bzero(&p->p_addr->u_pcb.pcb_fpregs, sizeof(struct fpframe));
488: else
489: #endif
490: m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
1.1 mw 491: #endif
492: }
493:
1.23 chopps 494: /*
495: * Info for CTL_HW
496: */
497: char cpu_model[120];
498: extern char version[];
1.81 is 499:
500: #if defined(M68060)
501: int m68060_pcr_init = 0x21; /* make this patchable */
502: #endif
503:
1.23 chopps 504:
1.61 veego 505: void
1.1 mw 506: identifycpu()
507: {
1.3 mw 508: /* there's alot of XXX in here... */
1.24 chopps 509: char *mach, *mmu, *fpu;
1.3 mw 510:
1.70 is 511: #ifdef M68060
512: char cpubuf[16];
513: u_int32_t pcr;
514: #endif
1.72 is 515:
1.66 is 516: #ifdef DRACO
517: char machbuf[16];
518:
519: if (is_draco()) {
1.80 christos 520: sprintf(machbuf, "DraCo rev.%d", is_draco());
1.66 is 521: mach = machbuf;
522: } else
523: #endif
1.23 chopps 524: if (is_a4000())
525: mach = "Amiga 4000";
526: else if (is_a3000())
527: mach = "Amiga 3000";
1.33 chopps 528: else if (is_a1200())
529: mach = "Amiga 1200";
1.3 mw 530: else
1.23 chopps 531: mach = "Amiga 500/2000";
1.1 mw 532:
1.31 chopps 533: fpu = NULL;
1.72 is 534: #ifdef M68060
1.66 is 535: if (machineid & AMIGA_68060) {
1.70 is 536: asm(".word 0x4e7a,0x0808; movl d0,%0" : "=d"(pcr) : : "d0");
1.80 christos 537: sprintf(cpubuf, "68%s060 rev.%d",
1.70 is 538: pcr & 0x10000 ? "LC/EC" : "", (pcr>>8)&0xff);
539: cpu_type = cpubuf;
1.66 is 540: mmu = "/MMU";
1.94 is 541: if (pcr & 2) {
542: fpu = "/FPU disabled";
543: fputype = FPU_NONE;
544: } else if (m68060_pcr_init & 2){
545: fpu = "/FPU will be disabled";
546: fputype = FPU_NONE;
547: } else if (machineid & AMIGA_FPU40) {
548: fpu = "/FPU";
549: fputype = FPU_68040; /* XXX */
550: }
1.72 is 551: } else
552: #endif
553: if (machineid & AMIGA_68040) {
1.5 mw 554: cpu_type = "m68040";
1.23 chopps 555: mmu = "/MMU";
1.24 chopps 556: fpu = "/FPU";
1.81 is 557: fputype = FPU_68040; /* XXX */
1.24 chopps 558: } else if (machineid & AMIGA_68030) {
1.23 chopps 559: cpu_type = "m68030"; /* XXX */
560: mmu = "/MMU";
561: } else {
562: cpu_type = "m68020";
563: mmu = " m68851 MMU";
564: }
1.31 chopps 565: if (fpu == NULL) {
1.52 chopps 566: if (machineid & AMIGA_68882) {
1.24 chopps 567: fpu = " m68882 FPU";
1.52 chopps 568: fputype = FPU_68882;
569: } else if (machineid & AMIGA_68881) {
1.24 chopps 570: fpu = " m68881 FPU";
1.52 chopps 571: fputype = FPU_68881;
572: } else {
1.24 chopps 573: fpu = " no FPU";
1.52 chopps 574: fputype = FPU_NONE;
575: }
1.24 chopps 576: }
1.80 christos 577: sprintf(cpu_model, "%s (%s CPU%s%s)", mach, cpu_type, mmu, fpu);
578: printf("%s\n", cpu_model);
1.23 chopps 579: }
1.5 mw 580:
1.23 chopps 581: /*
582: * machine dependent system variables.
583: */
1.61 veego 584: int
1.23 chopps 585: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
586: int *name;
587: u_int namelen;
588: void *oldp;
589: size_t *oldlenp;
590: void *newp;
591: size_t newlen;
592: struct proc *p;
593: {
594: dev_t consdev;
1.1 mw 595:
1.23 chopps 596: /* all sysctl names at this level are terminal */
597: if (namelen != 1)
598: return(ENOTDIR); /* overloaded */
599:
600: switch (name[0]) {
601: case CPU_CONSDEV:
602: if (cn_tab != NULL)
603: consdev = cn_tab->cn_dev;
1.5 mw 604: else
1.23 chopps 605: consdev = NODEV;
606: return(sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
607: sizeof(consdev)));
1.1 mw 608: default:
1.23 chopps 609: return(EOPNOTSUPP);
1.1 mw 610: }
1.23 chopps 611: /* NOTREACHED */
1.1 mw 612: }
613:
614: #define SS_RTEFRAME 1
615: #define SS_FPSTATE 2
616: #define SS_USERREGS 4
617:
618: struct sigstate {
619: int ss_flags; /* which of the following are valid */
620: struct frame ss_frame; /* original exception frame */
621: struct fpframe ss_fpstate; /* 68881/68882 state info */
622: };
623:
624: /*
625: * WARNING: code in locore.s assumes the layout shown for sf_signum
626: * thru sf_handler so... don't screw with them!
627: */
628: struct sigframe {
629: int sf_signum; /* signo for handler */
630: int sf_code; /* additional info for handler */
631: struct sigcontext *sf_scp; /* context ptr for handler */
632: sig_t sf_handler; /* handler addr for u_sigc */
633: struct sigstate sf_state; /* state of the hardware */
634: struct sigcontext sf_sc; /* actual context */
635: };
636:
637: #ifdef DEBUG
638: int sigdebug = 0x0;
639: int sigpid = 0;
640: #define SDB_FOLLOW 0x01
641: #define SDB_KSTACK 0x02
642: #define SDB_FPSTATE 0x04
643: #endif
644:
645: /*
646: * Send an interrupt to process.
647: */
648: void
649: sendsig(catcher, sig, mask, code)
650: sig_t catcher;
651: int sig, mask;
1.41 chopps 652: u_long code;
1.1 mw 653: {
654: register struct proc *p = curproc;
655: register struct sigframe *fp, *kfp;
656: register struct frame *frame;
1.23 chopps 657: register struct sigacts *psp = p->p_sigacts;
1.1 mw 658: register short ft;
1.23 chopps 659: int oonstack;
1.1 mw 660: extern short exframesize[];
661: extern char sigcode[], esigcode[];
662:
1.5 mw 663:
1.79 christos 664: #if 0
1.80 christos 665: printf("sendsig %d %d %x %x %x\n", p->p_pid, sig, mask, code, catcher);
1.79 christos 666: #endif
1.1 mw 667:
1.22 chopps 668: frame = (struct frame *)p->p_md.md_regs;
1.1 mw 669: ft = frame->f_format;
1.54 mycroft 670: oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
1.4 mw 671:
1.1 mw 672: /*
673: * Allocate and validate space for the signal handler
674: * context. Note that if the stack is in P0 space, the
675: * call to grow() is a nop, and the useracc() check
676: * will fail if the process has not already allocated
677: * the space with a `brk'.
678: */
1.23 chopps 679: if ((psp->ps_flags & SAS_ALTSTACK) && oonstack == 0 &&
680: (psp->ps_sigonstack & sigmask(sig))) {
1.60 jtc 681: fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
1.23 chopps 682: psp->ps_sigstk.ss_size - sizeof(struct sigframe));
1.54 mycroft 683: psp->ps_sigstk.ss_flags |= SS_ONSTACK;
1.1 mw 684: } else
1.23 chopps 685: fp = (struct sigframe *)frame->f_regs[SP] - 1;
1.1 mw 686: if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
687: (void)grow(p, (unsigned)fp);
688: #ifdef DEBUG
689: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1.80 christos 690: printf("sendsig(%d): sig %d ssp %p usp %p scp %p ft %d\n",
1.79 christos 691: p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
1.1 mw 692: #endif
1.23 chopps 693: if (useracc((caddr_t)fp, sizeof(struct sigframe), B_WRITE) == 0) {
1.1 mw 694: #ifdef DEBUG
695: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1.80 christos 696: printf("sendsig(%d): useracc failed on sig %d\n",
1.79 christos 697: p->p_pid, sig);
1.1 mw 698: #endif
699: /*
700: * Process has trashed its stack; give it an illegal
701: * instruction to halt it in its tracks.
702: */
703: SIGACTION(p, SIGILL) = SIG_DFL;
704: sig = sigmask(SIGILL);
705: p->p_sigignore &= ~sig;
706: p->p_sigcatch &= ~sig;
707: p->p_sigmask &= ~sig;
708: psignal(p, SIGILL);
709: return;
710: }
1.23 chopps 711: kfp = malloc(sizeof(struct sigframe), M_TEMP, M_WAITOK);
1.1 mw 712: /*
713: * Build the argument list for the signal handler.
714: */
715: kfp->sf_signum = sig;
716: kfp->sf_code = code;
717: kfp->sf_scp = &fp->sf_sc;
718: kfp->sf_handler = catcher;
719: /*
720: * Save necessary hardware state. Currently this includes:
721: * - general registers
722: * - original exception frame (if not a "normal" frame)
723: * - FP coprocessor state
724: */
725: kfp->sf_state.ss_flags = SS_USERREGS;
726: bcopy((caddr_t)frame->f_regs,
727: (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
728: if (ft >= FMT9) {
729: #ifdef DEBUG
730: if (ft != FMT9 && ft != FMTA && ft != FMTB)
731: panic("sendsig: bogus frame type");
732: #endif
733: kfp->sf_state.ss_flags |= SS_RTEFRAME;
734: kfp->sf_state.ss_frame.f_format = frame->f_format;
735: kfp->sf_state.ss_frame.f_vector = frame->f_vector;
736: bcopy((caddr_t)&frame->F_u,
737: (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
738: /*
739: * Leave an indicator that we need to clean up the kernel
740: * stack. We do this by setting the "pad word" above the
741: * hardware stack frame to the amount the stack must be
742: * adjusted by.
743: *
744: * N.B. we increment rather than just set f_stackadj in
745: * case we are called from syscall when processing a
746: * sigreturn. In that case, f_stackadj may be non-zero.
747: */
748: frame->f_stackadj += exframesize[ft];
749: frame->f_format = frame->f_vector = 0;
750: #ifdef DEBUG
751: if (sigdebug & SDB_FOLLOW)
1.80 christos 752: printf("sendsig(%d): copy out %d of frame %d\n",
1.79 christos 753: p->p_pid, exframesize[ft], ft);
1.1 mw 754: #endif
755: }
756: #ifdef FPCOPROC
757: kfp->sf_state.ss_flags |= SS_FPSTATE;
1.94 is 758: if (fputype)
759: m68881_save(&kfp->sf_state.ss_fpstate);
1.1 mw 760: #ifdef DEBUG
761: if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
1.80 christos 762: printf("sendsig(%d): copy out FP state (%x) to %p\n",
1.79 christos 763: p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
764: &kfp->sf_state.ss_fpstate);
1.1 mw 765: #endif
766: #endif
767: /*
768: * Build the signal context to be used by sigreturn.
769: */
770: kfp->sf_sc.sc_onstack = oonstack;
771: kfp->sf_sc.sc_mask = mask;
772: kfp->sf_sc.sc_sp = frame->f_regs[SP];
773: kfp->sf_sc.sc_fp = frame->f_regs[A6];
774: kfp->sf_sc.sc_ap = (int)&fp->sf_state;
775: kfp->sf_sc.sc_pc = frame->f_pc;
776: kfp->sf_sc.sc_ps = frame->f_sr;
1.23 chopps 777: (void) copyout((caddr_t)kfp, (caddr_t)fp, sizeof(struct sigframe));
1.1 mw 778: frame->f_regs[SP] = (int)fp;
779: #ifdef DEBUG
780: if (sigdebug & SDB_FOLLOW)
1.80 christos 781: printf("sendsig(%d): sig %d scp %p fp %p sc_sp %x sc_ap %x\n",
1.79 christos 782: p->p_pid, sig, kfp->sf_scp, fp,
783: kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
1.1 mw 784: #endif
785: /*
786: * Signal trampoline code is at base of user stack.
787: */
1.23 chopps 788: frame->f_pc = (int)(((char *)PS_STRINGS) - (esigcode - sigcode));
1.1 mw 789: #ifdef DEBUG
790: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1.80 christos 791: printf("sendsig(%d): sig %d returns\n",
1.79 christos 792: p->p_pid, sig);
1.1 mw 793: #endif
794: free((caddr_t)kfp, M_TEMP);
795: }
796:
1.4 mw 797:
1.1 mw 798: /*
799: * System call to cleanup state after a signal
800: * has been taken. Reset signal mask and
801: * stack state from context left by sendsig (above).
802: * Return to previous pc and psl as specified by
803: * context left by sendsig. Check carefully to
804: * make sure that the user has not modified the
805: * psl to gain improper priviledges or to cause
806: * a machine fault.
807: */
808: /* ARGSUSED */
1.58 mycroft 809: int
810: sys_sigreturn(p, v, retval)
1.23 chopps 811: struct proc *p;
1.56 thorpej 812: void *v;
813: register_t *retval;
814: {
1.58 mycroft 815: struct sys_sigreturn_args /* {
1.39 cgd 816: syscallarg(struct sigcontext *) sigcntxp;
1.56 thorpej 817: } */ *uap = v;
1.23 chopps 818: struct sigcontext *scp, context;
819: struct frame *frame;
820: int rf, flags;
1.1 mw 821: struct sigstate tstate;
822: extern short exframesize[];
823:
1.39 cgd 824: scp = SCARG(uap, sigcntxp);
1.1 mw 825: #ifdef DEBUG
826: if (sigdebug & SDB_FOLLOW)
1.80 christos 827: printf("sigreturn: pid %d, scp %p\n", p->p_pid, scp);
1.1 mw 828: #endif
829: if ((int)scp & 1)
1.23 chopps 830: return(EINVAL);
1.1 mw 831: /*
832: * Test and fetch the context structure.
833: * We grab it all at once for speed.
834: */
1.23 chopps 835: if (useracc((caddr_t)scp, sizeof(*scp), B_WRITE) == 0 ||
836: copyin(scp, &context, sizeof(context)))
837: return(EINVAL);
838: scp = &context;
1.1 mw 839: if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
1.23 chopps 840: return(EINVAL);
1.1 mw 841: /*
842: * Restore the user supplied information
843: */
1.23 chopps 844: if (scp->sc_onstack & 1)
1.54 mycroft 845: p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
1.23 chopps 846: else
1.54 mycroft 847: p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
1.1 mw 848: p->p_sigmask = scp->sc_mask &~ sigcantmask;
1.22 chopps 849: frame = (struct frame *) p->p_md.md_regs;
1.1 mw 850: frame->f_regs[SP] = scp->sc_sp;
851: frame->f_regs[A6] = scp->sc_fp;
852: frame->f_pc = scp->sc_pc;
853: frame->f_sr = scp->sc_ps;
854: /*
855: * Grab pointer to hardware state information.
856: * If zero, the user is probably doing a longjmp.
857: */
858: if ((rf = scp->sc_ap) == 0)
859: return (EJUSTRETURN);
860: /*
861: * See if there is anything to do before we go to the
862: * expense of copying in close to 1/2K of data
863: */
864: flags = fuword((caddr_t)rf);
865: #ifdef DEBUG
866: if (sigdebug & SDB_FOLLOW)
1.80 christos 867: printf("sigreturn(%d): sc_ap %x flags %x\n",
1.79 christos 868: p->p_pid, rf, flags);
1.1 mw 869: #endif
870: /*
871: * fuword failed (bogus sc_ap value).
872: */
873: if (flags == -1)
874: return (EINVAL);
875: if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
876: return (EJUSTRETURN);
877: #ifdef DEBUG
878: if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1.80 christos 879: printf("sigreturn(%d): ssp %p usp %x scp %p ft %d\n",
1.79 christos 880: p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
881: (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
1.1 mw 882: #endif
883: /*
884: * Restore most of the users registers except for A6 and SP
885: * which were handled above.
886: */
887: if (flags & SS_USERREGS)
888: bcopy((caddr_t)tstate.ss_frame.f_regs,
889: (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
890: /*
891: * Restore long stack frames. Note that we do not copy
892: * back the saved SR or PC, they were picked up above from
893: * the sigcontext structure.
894: */
895: if (flags & SS_RTEFRAME) {
896: register int sz;
897:
898: /* grab frame type and validate */
899: sz = tstate.ss_frame.f_format;
900: if (sz > 15 || (sz = exframesize[sz]) < 0)
901: return (EINVAL);
902: frame->f_stackadj -= sz;
903: frame->f_format = tstate.ss_frame.f_format;
904: frame->f_vector = tstate.ss_frame.f_vector;
905: bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
906: #ifdef DEBUG
907: if (sigdebug & SDB_FOLLOW)
1.80 christos 908: printf("sigreturn(%d): copy in %d of frame type %d\n",
1.79 christos 909: p->p_pid, sz, tstate.ss_frame.f_format);
1.1 mw 910: #endif
911: }
912: #ifdef FPCOPROC
913: /*
914: * Finally we restore the original FP context
915: */
1.94 is 916: #ifdef FPU_EMULATE
917: if ((flags & SS_FPSTATE) && fputype)
918: #else
919: if (fputype)
920: #endif
1.1 mw 921: m68881_restore(&tstate.ss_fpstate);
922: #ifdef DEBUG
923: if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
1.80 christos 924: printf("sigreturn(%d): copied in FP state (%x) at %p\n",
1.79 christos 925: p->p_pid, *(u_int *)&tstate.ss_fpstate,
1.1 mw 926: &tstate.ss_fpstate);
927: #endif
928: #endif
929: #ifdef DEBUG
930: if ((sigdebug & SDB_FOLLOW) ||
931: ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
1.80 christos 932: printf("sigreturn(%d): returns\n", p->p_pid);
1.1 mw 933: #endif
934: return (EJUSTRETURN);
935: }
1.4 mw 936:
1.3 mw 937: static int waittime = -1;
1.1 mw 938:
1.3 mw 939: void
940: bootsync(void)
1.1 mw 941: {
1.21 chopps 942: if (waittime < 0) {
1.1 mw 943: register struct buf *bp;
944: int iter, nbusy;
945:
946: waittime = 0;
947: (void) spl0();
1.80 christos 948: printf("syncing disks... ");
1.1 mw 949: /*
950: * Release vnodes held by texts before sync.
951: */
952: if (panicstr == 0)
953: vnode_pager_umount(NULL);
1.59 chopps 954: sys_sync(&proc0, (void *)NULL, (int *)NULL);
1.47 chopps 955: /*
956: * unmount filesystems
957: */
958: if (panicstr == 0)
959: vfs_unmountall();
1.1 mw 960:
961: for (iter = 0; iter < 20; iter++) {
962: nbusy = 0;
963: for (bp = &buf[nbuf]; --bp >= buf; )
964: if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
965: nbusy++;
966: if (nbusy == 0)
967: break;
1.80 christos 968: printf("%d ", nbusy);
1.30 chopps 969: delay(40000 * iter);
1.1 mw 970: }
971: if (nbusy)
1.80 christos 972: printf("giving up\n");
1.1 mw 973: else
1.80 christos 974: printf("done\n");
1.1 mw 975: /*
976: * If we've been adjusting the clock, the todr
977: * will be out of synch; adjust it now.
978: */
979: resettodr();
980: }
1.3 mw 981: }
982:
1.63 veego 983:
1.27 chopps 984: void
1.85 gwr 985: cpu_reboot(howto, bootstr)
1.3 mw 986: register int howto;
1.76 mrg 987: char *bootstr;
1.3 mw 988: {
989: /* take a snap shot before clobbering any registers */
990: if (curproc)
1.61 veego 991: savectx(&curproc->p_addr->u_pcb);
1.3 mw 992:
993: boothowto = howto;
1.61 veego 994: if ((howto & RB_NOSYNC) == 0)
1.3 mw 995: bootsync();
1.63 veego 996:
997: /* Disable interrupts. */
998: spl7();
999:
1000: /* If rebooting and a dump is requested do it. */
1001: if (howto & RB_DUMP)
1002: dumpsys();
1003:
1.61 veego 1004: if (howto & RB_HALT) {
1.80 christos 1005: printf("System halted.\n\n");
1.1 mw 1006: asm(" stop #0x2700");
1007: /*NOTREACHED*/
1008: }
1.63 veego 1009:
1010: doboot();
1.1 mw 1011: /*NOTREACHED*/
1012: }
1.63 veego 1013:
1.1 mw 1014:
1.3 mw 1015: unsigned dumpmag = 0x8fca0101; /* magic number for savecore */
1.1 mw 1016: int dumpsize = 0; /* also for savecore */
1017: long dumplo = 0;
1.68 mhitch 1018: cpu_kcore_hdr_t cpu_kcore_hdr;
1.1 mw 1019:
1.61 veego 1020: void
1.85 gwr 1021: cpu_dumpconf()
1.1 mw 1022: {
1.89 thorpej 1023: cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
1024: struct m68k_kcore_hdr *m = &h->un._m68k;
1.1 mw 1025: int nblks;
1.68 mhitch 1026: int i;
1027: extern u_int Sysseg_pa;
1.89 thorpej 1028: extern char end[];
1029:
1030: bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr));
1031:
1032: /*
1033: * Intitialize the `dispatcher' portion of the header.
1034: */
1035: strcpy(h->name, machine);
1036: h->page_size = NBPG;
1037: h->kernbase = KERNBASE;
1038:
1039: /*
1040: * Fill in information about our MMU configuration.
1041: */
1042: m->mmutype = mmutype;
1043: m->sg_v = SG_V;
1044: m->sg_frame = SG_FRAME;
1045: m->sg_ishift = SG_ISHIFT;
1046: m->sg_pmask = SG_PMASK;
1047: m->sg40_shift1 = SG4_SHIFT1;
1048: m->sg40_mask2 = SG4_MASK2;
1049: m->sg40_shift2 = SG4_SHIFT2;
1050: m->sg40_mask3 = SG4_MASK3;
1051: m->sg40_shift3 = SG4_SHIFT3;
1052: m->sg40_addr1 = SG4_ADDR1;
1053: m->sg40_addr2 = SG4_ADDR2;
1054: m->pg_v = PG_V;
1055: m->pg_frame = PG_FRAME;
1056:
1057: /*
1058: * Initialize the pointer to the kernel segment table.
1059: */
1060: m->sysseg_pa = Sysseg_pa;
1061:
1062: /*
1063: * Initialize relocation value such that:
1064: *
1065: * pa = (va - KERNBASE) + reloc
1066: */
1067: m->reloc = lowram;
1068:
1069: /*
1070: * Define the end of the relocatable range.
1071: */
1072: m->relocend = (u_int32_t)end;
1.1 mw 1073:
1.68 mhitch 1074: /* XXX new corefile format, single segment + chipmem */
1.1 mw 1075: dumpsize = physmem;
1.89 thorpej 1076: m->ram_segs[0].start = lowram;
1077: m->ram_segs[0].size = ctob(physmem);
1.68 mhitch 1078: for (i = 0; i < memlist->m_nseg; i++) {
1079: if ((memlist->m_seg[i].ms_attrib & MEMF_CHIP) == 0)
1080: continue;
1081: dumpsize += btoc(memlist->m_seg[i].ms_size);
1.89 thorpej 1082: m->ram_segs[1].start = 0;
1083: m->ram_segs[1].size = memlist->m_seg[i].ms_size;
1.68 mhitch 1084: break;
1085: }
1.1 mw 1086: if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
1087: nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
1088: if (dumpsize > btoc(dbtob(nblks - dumplo)))
1089: dumpsize = btoc(dbtob(nblks - dumplo));
1090: else if (dumplo == 0)
1.68 mhitch 1091: dumplo = nblks - btodb(ctob(dumpsize));
1.1 mw 1092: }
1.68 mhitch 1093: --dumplo; /* XXX assume header fits in one block */
1.1 mw 1094: /*
1095: * Don't dump on the first CLBYTES (why CLBYTES?)
1096: * in case the dump device includes a disk label.
1097: */
1098: if (dumplo < btodb(CLBYTES))
1099: dumplo = btodb(CLBYTES);
1100: }
1101:
1102: /*
1103: * Doadump comes here after turning off memory management and
1104: * getting on the dump stack, either when called above, or by
1105: * the auto-restart code.
1106: */
1.57 chopps 1107: #define BYTES_PER_DUMP MAXPHYS /* Must be a multiple of pagesize XXX small */
1.55 chopps 1108: static vm_offset_t dumpspace;
1109:
1110: vm_offset_t
1111: reserve_dumppages(p)
1112: vm_offset_t p;
1113: {
1114: dumpspace = p;
1115: return (p + BYTES_PER_DUMP);
1116: }
1117:
1.61 veego 1118: void
1.1 mw 1119: dumpsys()
1120: {
1.68 mhitch 1121: unsigned bytes, i, n, seg;
1.55 chopps 1122: int maddr, psize;
1123: daddr_t blkno;
1124: int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
1125: int error = 0;
1.68 mhitch 1126: kcore_seg_t *kseg_p;
1127: cpu_kcore_hdr_t *chdr_p;
1128: char dump_hdr[dbtob(1)]; /* XXX assume hdr fits in 1 block */
1.1 mw 1129:
1130: msgbufmapped = 0;
1131: if (dumpdev == NODEV)
1132: return;
1133: /*
1134: * For dumps during autoconfiguration,
1135: * if dump device has already configured...
1136: */
1137: if (dumpsize == 0)
1.85 gwr 1138: cpu_dumpconf();
1.1 mw 1139: if (dumplo < 0)
1140: return;
1.80 christos 1141: printf("\ndumping to dev %x, offset %ld\n", dumpdev, dumplo);
1.55 chopps 1142:
1143: psize = (*bdevsw[major(dumpdev)].d_psize) (dumpdev);
1.80 christos 1144: printf("dump ");
1.55 chopps 1145: if (psize == -1) {
1.80 christos 1146: printf("area unavailable.\n");
1.55 chopps 1147: return;
1148: }
1.68 mhitch 1149: kseg_p = (kcore_seg_t *)dump_hdr;
1150: chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
1151: bzero(dump_hdr, sizeof(dump_hdr));
1152:
1153: /*
1154: * Generate a segment header
1155: */
1156: CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
1157: kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
1158:
1159: /*
1160: * Add the md header
1161: */
1162:
1163: *chdr_p = cpu_kcore_hdr;
1164:
1.55 chopps 1165: bytes = ctob(dumpsize);
1.89 thorpej 1166: maddr = cpu_kcore_hdr.un._m68k.ram_segs[0].start;
1.68 mhitch 1167: seg = 0;
1.55 chopps 1168: blkno = dumplo;
1169: dump = bdevsw[major(dumpdev)].d_dump;
1.68 mhitch 1170: error = (*dump) (dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
1171: for (i = 0; i < bytes && error == 0; i += n) {
1.55 chopps 1172: /* Print out how many MBs we have to go. */
1173: n = bytes - i;
1174: if (n && (n % (1024 * 1024)) == 0)
1.80 christos 1175: printf("%d ", n / (1024 * 1024));
1.55 chopps 1176:
1177: /* Limit size for next transfer. */
1178: if (n > BYTES_PER_DUMP)
1179: n = BYTES_PER_DUMP;
1180:
1.68 mhitch 1181: if (maddr == 0) { /* XXX kvtop chokes on this */
1182: maddr += NBPG;
1183: n -= NBPG;
1184: i += NBPG;
1185: ++blkno; /* XXX skip physical page 0 */
1186: }
1.55 chopps 1187: (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
1188: error = (*dump) (dumpdev, blkno, (caddr_t) dumpspace, n);
1189: if (error)
1190: break;
1191: maddr += n;
1192: blkno += btodb(n); /* XXX? */
1.89 thorpej 1193: if (maddr >= (cpu_kcore_hdr.un._m68k.ram_segs[seg].start +
1194: cpu_kcore_hdr.un._m68k.ram_segs[seg].size)) {
1.68 mhitch 1195: ++seg;
1.89 thorpej 1196: maddr = cpu_kcore_hdr.un._m68k.ram_segs[seg].start;
1197: if (cpu_kcore_hdr.un._m68k.ram_segs[seg].size == 0)
1.68 mhitch 1198: break;
1199: }
1.55 chopps 1200: }
1201:
1202: switch (error) {
1.1 mw 1203:
1204: case ENXIO:
1.80 christos 1205: printf("device bad\n");
1.1 mw 1206: break;
1207:
1208: case EFAULT:
1.80 christos 1209: printf("device not ready\n");
1.1 mw 1210: break;
1211:
1212: case EINVAL:
1.80 christos 1213: printf("area improper\n");
1.1 mw 1214: break;
1215:
1216: case EIO:
1.80 christos 1217: printf("i/o error\n");
1.1 mw 1218: break;
1219:
1220: default:
1.80 christos 1221: printf("succeeded\n");
1.1 mw 1222: break;
1223: }
1.80 christos 1224: printf("\n\n");
1.55 chopps 1225: delay(5000000); /* 5 seconds */
1.1 mw 1226: }
1227:
1228: /*
1229: * Return the best possible estimate of the time in the timeval
1230: * to which tvp points. We do this by returning the current time
1231: * plus the amount of time since the last clock interrupt (clock.c:clkread).
1232: *
1233: * Check that this time is no less than any previously-reported time,
1234: * which could happen around the time of a clock adjustment. Just for fun,
1235: * we guarantee that the time will be greater than the value obtained by a
1236: * previous call.
1237: */
1.43 chopps 1238: void
1.1 mw 1239: microtime(tvp)
1240: register struct timeval *tvp;
1241: {
1.45 chopps 1242: int s = spl7();
1.1 mw 1243: static struct timeval lasttime;
1244:
1245: *tvp = time;
1246: tvp->tv_usec += clkread();
1247: while (tvp->tv_usec > 1000000) {
1248: tvp->tv_sec++;
1249: tvp->tv_usec -= 1000000;
1250: }
1251: if (tvp->tv_sec == lasttime.tv_sec &&
1252: tvp->tv_usec <= lasttime.tv_usec &&
1253: (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
1254: tvp->tv_sec++;
1255: tvp->tv_usec -= 1000000;
1256: }
1257: lasttime = *tvp;
1258: splx(s);
1259: }
1260:
1.61 veego 1261: void
1.1 mw 1262: initcpu()
1263: {
1.93 is 1264: typedef void trapfun __P((void));
1265:
1.67 is 1266: /* XXX should init '40 vecs here, too */
1.94 is 1267: #if defined(M68060) || defined(M68040) || defined(DRACO) || defined(FPU_EMULATE)
1.93 is 1268: extern trapfun *vectab[256];
1.70 is 1269: #endif
1.66 is 1270:
1.90 is 1271: #if defined(M68060) || defined(M68040)
1.93 is 1272: extern trapfun addrerr4060;
1.90 is 1273: #endif
1274:
1.72 is 1275: #ifdef M68060
1.93 is 1276: extern trapfun buserr60;
1.69 is 1277: #if defined(M060SP)
1.82 is 1278: /*extern u_int8_t I_CALL_TOP[];*/
1.93 is 1279: extern trapfun intemu60, fpiemu60, fpdemu60, fpeaemu60;
1.66 is 1280: extern u_int8_t FP_CALL_TOP[];
1.69 is 1281: #else
1.93 is 1282: extern trapfun illinst;
1.72 is 1283: #endif
1.93 is 1284: extern trapfun fpfault;
1.69 is 1285: #endif
1.66 is 1286:
1.90 is 1287: #ifdef M68040
1.93 is 1288: extern trapfun buserr40;
1.90 is 1289: #endif
1290:
1.70 is 1291: #ifdef DRACO
1.93 is 1292: extern trapfun DraCoIntr, DraCoLev1intr, DraCoLev2intr;
1.77 is 1293: u_char dracorev;
1.70 is 1294: #endif
1295:
1.94 is 1296: #ifdef FPU_EMULATE
1297: extern trapfun fpemuli;
1298: #endif
1299:
1.70 is 1300: #ifdef M68060
1.66 is 1301: if (machineid & AMIGA_68060) {
1.94 is 1302: if (machineid & AMIGA_FPU40 && m68060_pcr_init & 2) {
1303: /*
1304: * in this case, we're about to switch the FPU off;
1305: * do a FNOP to avoid stray FP traps later
1306: */
1307: __asm("fnop");
1308: /* ... and mark FPU as absent for identifyfpu() */
1309: machineid &= ~(AMIGA_FPU40|AMIGA_68882|AMIGA_68881);
1310: }
1.66 is 1311: asm volatile ("movl %0,d0; .word 0x4e7b,0x0808" : :
1312: "d"(m68060_pcr_init):"d0" );
1.90 is 1313:
1314: /* bus/addrerr vectors */
1.93 is 1315: vectab[2] = buserr60;
1316: vectab[3] = addrerr4060;
1.66 is 1317: #if defined(M060SP)
1318:
1319: /* integer support */
1.93 is 1320: vectab[61] = intemu60/*(trapfun *)&I_CALL_TOP[128 + 0x00]*/;
1.66 is 1321:
1322: /* floating point support */
1.81 is 1323: /*
1324: * XXX maybe we really should run-time check for the
1325: * stack frame format here:
1326: */
1.93 is 1327: vectab[11] = fpiemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x30]*/;
1.81 is 1328:
1.93 is 1329: vectab[55] = fpdemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x38]*/;
1330: vectab[60] = fpeaemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x40]*/;
1.66 is 1331:
1.93 is 1332: vectab[54] = (trapfun *)&FP_CALL_TOP[128 + 0x00];
1333: vectab[52] = (trapfun *)&FP_CALL_TOP[128 + 0x08];
1334: vectab[53] = (trapfun *)&FP_CALL_TOP[128 + 0x10];
1335: vectab[51] = (trapfun *)&FP_CALL_TOP[128 + 0x18];
1336: vectab[50] = (trapfun *)&FP_CALL_TOP[128 + 0x20];
1337: vectab[49] = (trapfun *)&FP_CALL_TOP[128 + 0x28];
1.66 is 1338:
1339: #else
1.93 is 1340: vectab[61] = illinst;
1.66 is 1341: #endif
1.93 is 1342: vectab[48] = fpfault;
1.66 is 1343: }
1344: #endif
1.70 is 1345:
1.81 is 1346: /*
1347: * Vector initialization for special motherboards
1348: */
1.90 is 1349: #ifdef M68040
1350: #ifdef M68060
1351: else
1352: #endif
1353: if (machineid & AMIGA_68040) {
1354: /* addrerr vector */
1.93 is 1355: vectab[2] = buserr40;
1356: vectab[3] = addrerr4060;
1.90 is 1357: }
1358: #endif
1.94 is 1359:
1360: #ifdef FPU_EMULATE
1361: if (!(machineid & (AMIGA_68881|AMIGA_68882|AMIGA_FPU40))) {
1362: vectab[11] = fpemuli;
1363: printf("FPU software emulation initialized.\n");
1364: }
1365: #endif
1366:
1367: /*
1368: * Vector initialization for special motherboards
1369: */
1.81 is 1370:
1.70 is 1371: #ifdef DRACO
1.77 is 1372: dracorev = is_draco();
1373: if (dracorev) {
1374: if (dracorev >= 4) {
1.93 is 1375: vectab[24+1] = DraCoLev1intr;
1376: vectab[24+2] = DraCoIntr;
1.77 is 1377: } else {
1.93 is 1378: vectab[24+1] = DraCoIntr;
1379: vectab[24+2] = DraCoLev2intr;
1.77 is 1380: }
1.93 is 1381: vectab[24+3] = DraCoIntr;
1382: vectab[24+4] = DraCoIntr;
1383: vectab[24+5] = DraCoIntr;
1384: vectab[24+6] = DraCoIntr;
1.70 is 1385: }
1386: #endif
1.66 is 1387: DCIS();
1.1 mw 1388: }
1389:
1.61 veego 1390: void
1.1 mw 1391: straytrap(pc, evec)
1392: int pc;
1393: u_short evec;
1394: {
1.80 christos 1395: printf("unexpected trap format %x (vector offset %x) from %x\n",
1.66 is 1396: evec>>12, evec & 0xFFF, pc);
1.42 chopps 1397: /*XXX*/ panic("straytrap");
1.1 mw 1398: }
1399:
1400: int *nofault;
1401:
1.61 veego 1402: int
1.1 mw 1403: badaddr(addr)
1404: register caddr_t addr;
1405: {
1406: register int i;
1407: label_t faultbuf;
1408:
1409: #ifdef lint
1410: i = *addr; if (i) return(0);
1411: #endif
1412: nofault = (int *) &faultbuf;
1413: if (setjmp((label_t *)nofault)) {
1414: nofault = (int *) 0;
1415: return(1);
1416: }
1417: i = *(volatile short *)addr;
1418: nofault = (int *) 0;
1419: return(0);
1420: }
1421:
1.61 veego 1422: int
1.1 mw 1423: badbaddr(addr)
1424: register caddr_t addr;
1425: {
1426: register int i;
1427: label_t faultbuf;
1428:
1429: #ifdef lint
1430: i = *addr; if (i) return(0);
1431: #endif
1432: nofault = (int *) &faultbuf;
1433: if (setjmp((label_t *)nofault)) {
1434: nofault = (int *) 0;
1435: return(1);
1436: }
1437: i = *(volatile char *)addr;
1438: nofault = (int *) 0;
1439: return(0);
1440: }
1441:
1.61 veego 1442: static void
1.1 mw 1443: netintr()
1444: {
1445: #ifdef INET
1.83 is 1446: #if NARP > 0
1.32 chopps 1447: if (netisr & (1 << NETISR_ARP)) {
1448: netisr &= ~(1 << NETISR_ARP);
1449: arpintr();
1450: }
1.22 chopps 1451: #endif
1.1 mw 1452: if (netisr & (1 << NETISR_IP)) {
1453: netisr &= ~(1 << NETISR_IP);
1454: ipintr();
1.88 christos 1455: }
1456: #endif
1457: #ifdef NETATALK
1458: if (netisr & (1 << NETISR_ATALK)) {
1459: netisr &= ~(1 << NETISR_ATALK);
1460: atintr();
1.1 mw 1461: }
1462: #endif
1463: #ifdef NS
1464: if (netisr & (1 << NETISR_NS)) {
1465: netisr &= ~(1 << NETISR_NS);
1466: nsintr();
1467: }
1468: #endif
1469: #ifdef ISO
1470: if (netisr & (1 << NETISR_ISO)) {
1471: netisr &= ~(1 << NETISR_ISO);
1472: clnlintr();
1.53 paulus 1473: }
1474: #endif
1475: #if NPPP > 0
1476: if (netisr & (1 << NETISR_PPP)) {
1477: netisr &= ~(1 << NETISR_PPP);
1478: pppintr();
1.1 mw 1479: }
1480: #endif
1481: }
1482:
1.3 mw 1483:
1.31 chopps 1484: /*
1485: * this is a handy package to have asynchronously executed
1486: * function calls executed at very low interrupt priority.
1487: * Example for use is keyboard repeat, where the repeat
1488: * handler running at splclock() triggers such a (hardware
1489: * aided) software interrupt.
1490: * Note: the installed functions are currently called in a
1491: * LIFO fashion, might want to change this to FIFO
1492: * later.
1493: */
1.3 mw 1494: struct si_callback {
1.31 chopps 1495: struct si_callback *next;
1496: void (*function) __P((void *rock1, void *rock2));
1497: void *rock1, *rock2;
1.3 mw 1498: };
1.31 chopps 1499: static struct si_callback *si_callbacks;
1.42 chopps 1500: static struct si_callback *si_free;
1501: #ifdef DIAGNOSTIC
1502: static int ncb; /* number of callback blocks allocated */
1503: static int ncbd; /* number of callback blocks dynamically allocated */
1504: #endif
1505:
1.95 is 1506: /*
1507: * these are __GENERIC_SOFT_INTERRUPT wrappers; will be replaced
1508: * once by the real thing once all drivers are converted.
1509: *
1510: * to help performance for converted drivers, the YYY_sicallback() function
1511: * family can be implemented in terms of softintr_XXX() as an intermediate
1512: * measure.
1513: */
1514:
1515: static void
1516: _softintr_callit(rock1, rock2)
1517: void *rock1, *rock2;
1518: {
1519: (*(void (*)(void *))rock1)(rock2);
1520: }
1521:
1522: void *
1523: softintr_establish(ipl, func, arg)
1524: int ipl;
1525: void func __P((void *));
1526: void *arg;
1527: {
1528: struct si_callback *si;
1529:
1530: (void)ipl;
1531:
1532: si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
1533: if (si == NULL)
1534: return (si);
1535:
1536: si->function = (void *)0;
1537: si->rock1 = (void *)func;
1538: si->rock2 = arg;
1539:
1540: alloc_sicallback();
1541: return ((void *)si);
1542: }
1543:
1544:
1.42 chopps 1545: void
1546: alloc_sicallback()
1547: {
1548: struct si_callback *si;
1549: int s;
1550:
1551: si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
1552: if (si == NULL)
1553: return;
1554: s = splhigh();
1555: si->next = si_free;
1556: si_free = si;
1557: splx(s);
1558: #ifdef DIAGNOSTIC
1559: ++ncb;
1560: #endif
1.95 is 1561: }
1562:
1563: void
1564: softintr_schedule(vsi)
1565: void *vsi;
1566: {
1567: struct si_callback *si;
1568: si = vsi;
1569:
1570: add_sicallback(_softintr_callit, si->rock1, si->rock2);
1.42 chopps 1571: }
1.3 mw 1572:
1573: void
1574: add_sicallback (function, rock1, rock2)
1.31 chopps 1575: void (*function) __P((void *rock1, void *rock2));
1576: void *rock1, *rock2;
1.3 mw 1577: {
1.31 chopps 1578: struct si_callback *si;
1579: int s;
1.3 mw 1580:
1.31 chopps 1581: /*
1582: * this function may be called from high-priority interrupt handlers.
1583: * We may NOT block for memory-allocation in here!.
1584: */
1.42 chopps 1585: s = splhigh();
1586: si = si_free;
1587: if (si != NULL)
1588: si_free = si->next;
1589: splx(s);
1590:
1591: if (si == NULL) {
1592: si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
1593: #ifdef DIAGNOSTIC
1594: if (si)
1595: ++ncbd; /* count # dynamically allocated */
1596: #endif
1.3 mw 1597:
1.42 chopps 1598: if (!si)
1599: return;
1600: }
1.3 mw 1601:
1.31 chopps 1602: si->function = function;
1603: si->rock1 = rock1;
1604: si->rock2 = rock2;
1.3 mw 1605:
1.31 chopps 1606: s = splhigh();
1607: si->next = si_callbacks;
1608: si_callbacks = si;
1609: splx(s);
1.3 mw 1610:
1.31 chopps 1611: /*
1.45 chopps 1612: * Cause a software interrupt (spl1). This interrupt might
1.31 chopps 1613: * happen immediately, or after returning to a safe enough level.
1614: */
1.45 chopps 1615: setsoftcback();
1.3 mw 1616: }
1617:
1618:
1619: void
1.31 chopps 1620: rem_sicallback(function)
1621: void (*function) __P((void *rock1, void *rock2));
1.3 mw 1622: {
1.31 chopps 1623: struct si_callback *si, *psi, *nsi;
1624: int s;
1.3 mw 1625:
1.31 chopps 1626: s = splhigh();
1627: for (psi = 0, si = si_callbacks; si; ) {
1628: nsi = si->next;
1.3 mw 1629:
1.31 chopps 1630: if (si->function != function)
1631: psi = si;
1632: else {
1.42 chopps 1633: /* free(si, M_TEMP); */
1634: si->next = si_free;
1635: si_free = si;
1.31 chopps 1636: if (psi)
1637: psi->next = nsi;
1638: else
1639: si_callbacks = nsi;
1640: }
1641: si = nsi;
1.3 mw 1642: }
1.31 chopps 1643: splx(s);
1.3 mw 1644: }
1645:
1646: /* purge the list */
1647: static void
1.31 chopps 1648: call_sicallbacks()
1.3 mw 1649: {
1.31 chopps 1650: struct si_callback *si;
1651: int s;
1.42 chopps 1652: void *rock1, *rock2;
1653: void (*function) __P((void *, void *));
1.3 mw 1654:
1.31 chopps 1655: do {
1656: s = splhigh ();
1.61 veego 1657: if ((si = si_callbacks) != 0)
1.31 chopps 1658: si_callbacks = si->next;
1659: splx(s);
1660:
1661: if (si) {
1.42 chopps 1662: function = si->function;
1663: rock1 = si->rock1;
1664: rock2 = si->rock2;
1665: /* si->function(si->rock1, si->rock2); */
1666: /* free(si, M_TEMP); */
1667: s = splhigh ();
1668: si->next = si_free;
1669: si_free = si;
1670: splx(s);
1671: function (rock1, rock2);
1.31 chopps 1672: }
1673: } while (si);
1.42 chopps 1674: #ifdef DIAGNOSTIC
1675: if (ncbd) {
1.44 chopps 1676: ncb += ncbd;
1.80 christos 1677: printf("call_sicallback: %d more dynamic structures %d total\n",
1.42 chopps 1678: ncbd, ncb);
1679: ncbd = 0;
1680: }
1681: #endif
1.3 mw 1682: }
1683:
1.45 chopps 1684: struct isr *isr_ports;
1.66 is 1685: #ifdef DRACO
1686: struct isr *isr_slot3;
1.81 is 1687: struct isr *isr_supio;
1.66 is 1688: #endif
1.45 chopps 1689: struct isr *isr_exter;
1690:
1691: void
1692: add_isr(isr)
1693: struct isr *isr;
1694: {
1695: struct isr **p, *q;
1696:
1.66 is 1697: #ifdef DRACO
1698: switch (isr->isr_ipl) {
1699: case 2:
1700: p = &isr_ports;
1701: break;
1702: case 3:
1703: p = &isr_slot3;
1704: break;
1.81 is 1705: case 5:
1706: p = &isr_supio;
1707: break;
1.70 is 1708: default: /* was case 6:; make gcc -Wall quiet */
1.66 is 1709: p = &isr_exter;
1710: break;
1711: }
1712: #else
1.45 chopps 1713: p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter;
1.66 is 1714: #endif
1.45 chopps 1715: while ((q = *p) != NULL)
1716: p = &q->isr_forw;
1717: isr->isr_forw = NULL;
1718: *p = isr;
1719: /* enable interrupt */
1.66 is 1720: #ifdef DRACO
1721: if (is_draco())
1.81 is 1722: switch(isr->isr_ipl) {
1723: case 6:
1724: *draco_intena |= DRIRQ_INT6;
1725: break;
1726: case 2:
1727: *draco_intena |= DRIRQ_INT2;
1728: break;
1729: default:
1730: break;
1731: }
1.66 is 1732: else
1733: #endif
1734: custom.intena = isr->isr_ipl == 2 ?
1735: INTF_SETCLR | INTF_PORTS :
1736: INTF_SETCLR | INTF_EXTER;
1.45 chopps 1737: }
1738:
1739: void
1740: remove_isr(isr)
1741: struct isr *isr;
1742: {
1743: struct isr **p, *q;
1744:
1.66 is 1745: #ifdef DRACO
1746: switch (isr->isr_ipl) {
1747: case 2:
1748: p = &isr_ports;
1749: break;
1750: case 3:
1751: p = &isr_slot3;
1752: break;
1.81 is 1753: case 5:
1754: p = &isr_supio;
1755: break;
1.70 is 1756: default: /* XXX to make gcc -Wall quiet, was 6: */
1.66 is 1757: p = &isr_exter;
1758: break;
1759: }
1760: #else
1.45 chopps 1761: p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66 is 1762: #endif
1763:
1.45 chopps 1764: while ((q = *p) != NULL && q != isr)
1765: p = &q->isr_forw;
1766: if (q)
1767: *p = q->isr_forw;
1768: else
1769: panic("remove_isr: handler not registered");
1770: /* disable interrupt if no more handlers */
1.66 is 1771: #ifdef DRACO
1772: switch (isr->isr_ipl) {
1773: case 2:
1774: p = &isr_ports;
1775: break;
1776: case 3:
1777: p = &isr_slot3;
1778: break;
1.81 is 1779: case 5:
1780: p = &isr_supio;
1781: break;
1.66 is 1782: case 6:
1783: p = &isr_exter;
1784: break;
1785: }
1786: #else
1.45 chopps 1787: p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66 is 1788: #endif
1.45 chopps 1789: if (*p == NULL)
1.66 is 1790: #ifdef DRACO
1.81 is 1791: if (is_draco()) {
1792: switch(isr->isr_ipl) {
1793: case 2:
1794: *draco_intena &= ~DRIRQ_INT2;
1795: break;
1796: case 6:
1797: *draco_intena &= ~DRIRQ_INT6;
1798: break;
1799: default:
1800: break;
1801: }
1802: } else
1.66 is 1803: #endif
1804: custom.intena = isr->isr_ipl == 6 ?
1805: INTF_EXTER : INTF_PORTS;
1.45 chopps 1806: }
1807:
1.61 veego 1808: void
1.1 mw 1809: intrhand(sr)
1810: int sr;
1811: {
1.22 chopps 1812: register unsigned int ipl;
1813: register unsigned short ireq;
1.45 chopps 1814: register struct isr **p, *q;
1.1 mw 1815:
1.22 chopps 1816: ipl = (sr >> 8) & 7;
1.66 is 1817: #ifdef REALLYDEBUG
1.80 christos 1818: printf("intrhand: got int. %d\n", ipl);
1.66 is 1819: #endif
1820: #ifdef DRACO
1821: if (is_draco())
1822: ireq = ((ipl == 1) && (*draco_intfrc & DRIRQ_SOFT) ?
1823: INTF_SOFTINT : 0);
1824: else
1825: #endif
1826: ireq = custom.intreqr;
1.1 mw 1827:
1.22 chopps 1828: switch (ipl) {
1829: case 1:
1.66 is 1830: #ifdef DRACO
1831: if (is_draco() && (draco_ioct->io_status & DRSTAT_KBDRECV))
1832: drkbdintr();
1833: #endif
1.22 chopps 1834: if (ireq & INTF_TBE) {
1835: #if NSER > 0
1836: ser_outintr();
1837: #else
1838: custom.intreq = INTF_TBE;
1839: #endif
1840: }
1841:
1842: if (ireq & INTF_DSKBLK) {
1.17 chopps 1843: #if NFD > 0
1.22 chopps 1844: fdintr(0);
1.17 chopps 1845: #endif
1.22 chopps 1846: custom.intreq = INTF_DSKBLK;
1847: }
1848: if (ireq & INTF_SOFTINT) {
1.61 veego 1849: unsigned char ssir_active;
1850: int s;
1851:
1.22 chopps 1852: /*
1.36 chopps 1853: * first clear the softint-bit
1.45 chopps 1854: * then process all classes of softints.
1.36 chopps 1855: * this order is dicated by the nature of
1856: * software interrupts. The other order
1.61 veego 1857: * allows software interrupts to be missed.
1858: * Also copy and clear ssir to prevent
1859: * interrupt loss.
1.22 chopps 1860: */
1.45 chopps 1861: clrsoftint();
1.61 veego 1862: s = splhigh();
1863: ssir_active = ssir;
1864: siroff(SIR_NET | SIR_CLOCK | SIR_CBACK);
1865: splx(s);
1866: if (ssir_active & SIR_NET) {
1.66 is 1867: #ifdef REALLYDEBUG
1.80 christos 1868: printf("calling netintr\n");
1.66 is 1869: #endif
1.45 chopps 1870: cnt.v_soft++;
1871: netintr();
1872: }
1.61 veego 1873: if (ssir_active & SIR_CLOCK) {
1.66 is 1874: #ifdef REALLYDEBUG
1.80 christos 1875: printf("calling softclock\n");
1.66 is 1876: #endif
1.45 chopps 1877: cnt.v_soft++;
1878: /* XXXX softclock(&frame.f_stackadj); */
1879: softclock();
1880: }
1.61 veego 1881: if (ssir_active & SIR_CBACK) {
1.66 is 1882: #ifdef REALLYDEBUG
1.80 christos 1883: printf("calling softcallbacks\n");
1.66 is 1884: #endif
1.45 chopps 1885: cnt.v_soft++;
1886: call_sicallbacks();
1887: }
1.22 chopps 1888: }
1889: break;
1890:
1891: case 2:
1.45 chopps 1892: p = &isr_ports;
1893: while ((q = *p) != NULL) {
1894: if ((q->isr_intr)(q->isr_arg))
1895: break;
1896: p = &q->isr_forw;
1897: }
1898: if (q == NULL)
1899: ciaa_intr ();
1.66 is 1900: #ifdef DRACO
1901: if (is_draco())
1902: *draco_intpen &= ~DRIRQ_INT2;
1903: else
1904: #endif
1905: custom.intreq = INTF_PORTS;
1.22 chopps 1906: break;
1.5 mw 1907: case 3:
1.1 mw 1908: /* VBL */
1.45 chopps 1909: if (ireq & INTF_BLIT)
1.22 chopps 1910: blitter_handler();
1.45 chopps 1911: if (ireq & INTF_COPER)
1.22 chopps 1912: copper_handler();
1.45 chopps 1913: if (ireq & INTF_VERTB)
1.22 chopps 1914: vbl_handler();
1915: break;
1.81 is 1916: #ifdef DRACO
1917: case 5:
1918: p = &isr_supio;
1919: while ((q = *p) != NULL) {
1920: if ((q->isr_intr)(q->isr_arg))
1921: break;
1922: p = &q->isr_forw;
1923: }
1924: break;
1925: #endif
1.3 mw 1926: #if 0
1927: /* now dealt with in locore.s for speed reasons */
1.22 chopps 1928: case 5:
1929: /* check RS232 RBF */
1930: serintr (0);
1931:
1932: custom.intreq = INTF_DSKSYNC;
1933: break;
1934: #endif
1935:
1936: case 4:
1.66 is 1937: #ifdef DRACO
1938: #include "drsc.h"
1939: if (is_draco())
1940: #if NDRSC > 0
1941: drsc_handler();
1942: #else
1943: *draco_intpen &= ~DRIRQ_SCSI;
1944: #endif
1945: else
1946: #endif
1.22 chopps 1947: audio_handler();
1948: break;
1949: default:
1.80 christos 1950: printf("intrhand: unexpected sr 0x%x, intreq = 0x%x\n",
1.22 chopps 1951: sr, ireq);
1952: break;
1953: }
1.66 is 1954: #ifdef REALLYDEBUG
1.80 christos 1955: printf("intrhand: leaving.\n");
1.66 is 1956: #endif
1.1 mw 1957: }
1958:
1959: #if defined(DEBUG) && !defined(PANICBUTTON)
1960: #define PANICBUTTON
1961: #endif
1962:
1963: #ifdef PANICBUTTON
1964: int panicbutton = 1; /* non-zero if panic buttons are enabled */
1965: int crashandburn = 0;
1966: int candbdelay = 50; /* give em half a second */
1.61 veego 1967: void candbtimer __P((void));
1.1 mw 1968:
1.61 veego 1969: void
1.1 mw 1970: candbtimer()
1971: {
1972: crashandburn = 0;
1973: }
1974: #endif
1975:
1976: #if 0
1977: /*
1978: * Level 7 interrupts can be caused by the keyboard or parity errors.
1979: */
1980: nmihand(frame)
1981: struct frame frame;
1982: {
1983: if (kbdnmi()) {
1984: #ifdef PANICBUTTON
1985: static int innmihand = 0;
1986:
1987: /*
1988: * Attempt to reduce the window of vulnerability for recursive
1989: * NMIs (e.g. someone holding down the keyboard reset button).
1990: */
1991: if (innmihand == 0) {
1992: innmihand = 1;
1.80 christos 1993: printf("Got a keyboard NMI\n");
1.1 mw 1994: innmihand = 0;
1995: }
1996: if (panicbutton) {
1997: if (crashandburn) {
1998: crashandburn = 0;
1999: panic(panicstr ?
2000: "forced crash, nosync" : "forced crash");
2001: }
2002: crashandburn++;
2003: timeout(candbtimer, (caddr_t)0, candbdelay);
2004: }
2005: #endif
2006: return;
2007: }
2008: if (parityerror(&frame))
2009: return;
2010: /* panic?? */
1.80 christos 2011: printf("unexpected level 7 interrupt ignored\n");
1.1 mw 2012: }
2013: #endif
2014:
1.31 chopps 2015: /*
2016: * should only get here, if no standard executable. This can currently
2017: * only mean, we're reading an old ZMAGIC file without MID, but since Amiga
2018: * ZMAGIC always worked the `right' way (;-)) just ignore the missing
2019: * MID and proceed to new zmagic code ;-)
2020: */
1.61 veego 2021: int
1.4 mw 2022: cpu_exec_aout_makecmds(p, epp)
1.31 chopps 2023: struct proc *p;
2024: struct exec_package *epp;
1.1 mw 2025: {
1.31 chopps 2026: int error = ENOEXEC;
1.71 veego 2027: #ifdef COMPAT_NOMID
1.31 chopps 2028: struct exec *execp = epp->ep_hdr;
1.71 veego 2029: #endif
1.1 mw 2030:
2031: #ifdef COMPAT_NOMID
1.31 chopps 2032: if (!((execp->a_midmag >> 16) & 0x0fff)
2033: && execp->a_midmag == ZMAGIC)
2034: return(exec_aout_prep_zmagic(p, epp));
1.1 mw 2035: #endif
1.4 mw 2036: #ifdef COMPAT_SUNOS
1.31 chopps 2037: {
1.41 chopps 2038: extern sunos_exec_aout_makecmds
1.31 chopps 2039: __P((struct proc *, struct exec_package *));
1.41 chopps 2040: if ((error = sunos_exec_aout_makecmds(p, epp)) == 0)
1.31 chopps 2041: return(0);
2042: }
1.4 mw 2043: #endif
1.31 chopps 2044: return(error);
1.4 mw 2045: }
CVSweb <webmaster@jp.NetBSD.org>