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