[BACK]Return to machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / amiga / amiga

Annotation of src/sys/arch/amiga/amiga/machdep.c, Revision 1.141.2.4

1.141.2.4! bouyer      1: /*     $NetBSD: machdep.c,v 1.141.2.3 2001/02/11 19:08:41 bouyer 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:  */
1.116     jonathan   44:
                     45: #include "opt_ddb.h"
1.120     jonathan   46: #include "opt_compat_netbsd.h"
1.1       mw         47:
1.9       chopps     48: #include <sys/param.h>
                     49: #include <sys/systm.h>
1.141.2.1  bouyer     50: #include <sys/callout.h>
1.9       chopps     51: #include <sys/signalvar.h>
                     52: #include <sys/kernel.h>
                     53: #include <sys/map.h>
                     54: #include <sys/proc.h>
                     55: #include <sys/buf.h>
                     56: #include <sys/reboot.h>
                     57: #include <sys/conf.h>
                     58: #include <sys/file.h>
                     59: #include <sys/clist.h>
                     60: #include <sys/malloc.h>
                     61: #include <sys/mbuf.h>
                     62: #include <sys/msgbuf.h>
1.5       mw         63: #include <sys/user.h>
                     64: #include <sys/exec.h>            /* for PS_STRINGS */
1.23      chopps     65: #include <sys/vnode.h>
1.124     veego      66: #include <sys/device.h>
1.23      chopps     67: #include <sys/queue.h>
1.39      cgd        68: #include <sys/mount.h>
                     69: #include <sys/syscallargs.h>
1.68      mhitch     70: #include <sys/core.h>
                     71: #include <sys/kcore.h>
1.141.2.1  bouyer     72:
1.141.2.4! bouyer     73: #if defined(DDB) && defined(__ELF__)
        !            74: #include <sys/exec_elf.h>
        !            75: #endif
        !            76:
1.9       chopps     77: #include <net/netisr.h>
1.141.2.1  bouyer     78: #undef PS      /* XXX netccitt/pk.h conflict with machine/reg.h? */
1.103     is         79:
1.141.2.1  bouyer     80: #define        MAXMEM  64*1024 /* XXX - from cmap.h */
1.121     mhitch     81: #include <uvm/uvm_extern.h>
                     82:
1.103     is         83: #include <sys/sysctl.h>
1.61      veego      84:
                     85: #include <machine/db_machdep.h>
                     86: #include <ddb/db_sym.h>
                     87: #include <ddb/db_extern.h>
                     88:
1.23      chopps     89: #include <machine/cpu.h>
                     90: #include <machine/reg.h>
                     91: #include <machine/psl.h>
                     92: #include <machine/pte.h>
1.68      mhitch     93: #include <machine/kcore.h>
1.23      chopps     94: #include <dev/cons.h>
                     95: #include <amiga/amiga/isr.h>
1.9       chopps     96: #include <amiga/amiga/custom.h>
1.66      is         97: #ifdef DRACO
                     98: #include <amiga/amiga/drcustom.h>
1.122     is         99: #include <m68k/include/asm_single.h>
1.66      is        100: #endif
1.9       chopps    101: #include <amiga/amiga/cia.h>
                    102: #include <amiga/amiga/cc.h>
                    103: #include <amiga/amiga/memlist.h>
1.45      chopps    104:
1.17      chopps    105: #include "fd.h"
1.22      chopps    106: #include "ser.h"
1.1       mw        107:
1.61      veego     108: /* prototypes */
                    109: void identifycpu __P((void));
                    110: vm_offset_t reserve_dumppages __P((vm_offset_t));
                    111: void dumpsys __P((void));
                    112: void initcpu __P((void));
                    113: void straytrap __P((int, u_short));
                    114: static void netintr __P((void));
                    115: static void call_sicallbacks __P((void));
1.95      is        116: static void _softintr_callit __P((void *, void *));
1.61      veego     117: void intrhand __P((int));
1.64      mhitch    118: #if NSER > 0
                    119: void ser_outintr __P((void));
                    120: #endif
                    121: #if NFD > 0
                    122: void fdintr __P((int));
                    123: #endif
1.61      veego     124:
1.1       mw        125: /*
1.111     is        126:  * patched by some devices at attach time (currently, only the coms)
1.81      is        127:  */
1.111     is        128: u_int16_t amiga_serialspl = PSL_S|PSL_IPL4;
1.81      is        129:
1.121     mhitch    130: vm_map_t exec_map = NULL;
                    131: vm_map_t mb_map = NULL;
                    132: vm_map_t phys_map = NULL;
                    133:
1.100     leo       134: caddr_t        msgbufaddr;
1.141     is        135: paddr_t msgbufpa;
1.100     leo       136:
1.1       mw        137: int    maxmem;                 /* max memory per process */
                    138: int    physmem = MAXMEM;       /* max supported memory, changes to actual */
                    139: /*
1.45      chopps    140:  * extender "register" for software interrupts. Moved here
                    141:  * from locore.s, since softints are no longer dealt with
                    142:  * in locore.s.
                    143:  */
                    144: unsigned char ssir;
                    145: /*
1.1       mw        146:  * safepri is a safe priority for sleep to set for a spin-wait
                    147:  * during autoconfiguration or after a panic.
                    148:  */
                    149: int    safepri = PSL_LOWIPL;
                    150: extern  int   freebufspace;
                    151: extern u_int lowram;
                    152:
                    153: /* used in init_main.c */
1.91      veego     154: char   *cpu_type = "m68k";
1.23      chopps    155: /* the following is used externally (sysctl_hw) */
1.91      veego     156: char   machine[] = MACHINE;    /* from <machine/param.h> */
1.141.2.1  bouyer    157:
                    158: /* Our exported CPU info; we can have only one. */
                    159: struct cpu_info cpu_info_store;
1.23      chopps    160:
1.102     mhitch    161: /*
                    162:  * current open serial device speed;  used by some SCSI drivers to reduce
                    163:  * DMA transfer lengths.
                    164:  */
                    165: int    ser_open_speed;
                    166:
1.5       mw        167:  /*
1.1       mw        168:  * Console initialization: called early on from main,
                    169:  * before vm init or startup.  Do enough configuration
                    170:  * to choose and initialize a console.
                    171:  */
                    172: void
                    173: consinit()
                    174: {
1.5       mw        175:        /* initialize custom chip interface */
1.66      is        176: #ifdef DRACO
                    177:        if (is_draco()) {
                    178:                /* XXX to be done */
                    179:        } else
                    180: #endif
                    181:                custom_chips_init();
1.1       mw        182:        /*
                    183:         * Initialize the console before we print anything out.
                    184:         */
                    185:        cninit();
1.11      chopps    186:
                    187: #if defined (DDB)
1.114     tv        188:        {
1.115     mhitch    189:                extern int end[];
1.114     tv        190:                extern int *esym;
                    191:
1.141.2.4! bouyer    192: #ifndef __ELF__
1.114     tv        193:                ddb_init(*(int *)&end, ((int *)&end) + 1, esym);
1.141.2.4! bouyer    194: #else
        !           195:                ddb_init((int)esym - (int)&end - sizeof(Elf32_Ehdr),
        !           196:                    (void *)&end, esym);
        !           197: #endif
1.114     tv        198:        }
1.11      chopps    199:         if (boothowto & RB_KDB)
                    200:                 Debugger();
                    201: #endif
1.1       mw        202: }
                    203:
                    204: /*
                    205:  * cpu_startup: allocate memory for variable-sized tables,
                    206:  * initialize cpu, and do autoconfiguration.
                    207:  */
                    208: void
                    209: cpu_startup()
                    210: {
                    211:        register unsigned i;
1.136     lukem     212:        caddr_t v;
1.1       mw        213:        int base, residual;
1.136     lukem     214:        char pbuf[9];
1.1       mw        215: #ifdef DEBUG
                    216:        extern int pmapdebug;
                    217:        int opmapdebug = pmapdebug;
                    218: #endif
1.141     is        219:        paddr_t minaddr, maxaddr;
                    220:        paddr_t size = 0;
1.1       mw        221:
                    222:        /*
                    223:         * Initialize error message buffer (at end of core).
                    224:         */
                    225: #ifdef DEBUG
                    226:        pmapdebug = 0;
                    227: #endif
1.111     is        228:        /*
                    229:         * pmap_bootstrap has positioned this at the end of kernel
                    230:         * memory segment - map and initialize it now.
                    231:         */
                    232:
1.100     leo       233:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
1.141     is        234:                pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * NBPG,
1.141.2.1  bouyer    235:                    msgbufpa + i * NBPG, VM_PROT_READ|VM_PROT_WRITE,
                    236:                    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
1.100     leo       237:        initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
1.1       mw        238:
                    239:        /*
                    240:         * Good {morning,afternoon,evening,night}.
                    241:         */
1.80      christos  242:        printf(version);
1.1       mw        243:        identifycpu();
1.136     lukem     244:        format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
                    245:        printf("total memory = %s\n", pbuf);
1.5       mw        246:
1.1       mw        247:        /*
1.136     lukem     248:         * Find out how much space we need, allocate it,
                    249:         * and then give everything true virtual addresses.
1.1       mw        250:         */
1.136     lukem     251:        size = (vm_size_t)allocsys(NULL, NULL);
                    252:        if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(size))) == 0)
                    253:                panic("startup: no room for tables");
                    254:        if (allocsys(v, NULL) - v != size)
1.1       mw        255:                panic("startup: table size inconsistency");
                    256:
                    257:        /*
                    258:         * Now allocate buffers proper.  They are different than the above
                    259:         * in that they usually occupy more virtual memory than physical.
                    260:         */
                    261:        size = MAXBSIZE * nbuf;
1.121     mhitch    262:        if (uvm_map(kernel_map, (vm_offset_t *)&buffers, round_page(size),
1.141.2.1  bouyer    263:            NULL, UVM_UNKNOWN_OFFSET, 0,
1.121     mhitch    264:            UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
                    265:            UVM_ADV_NORMAL, 0)) != KERN_SUCCESS)
                    266:                panic("startup: cannot allocate VM for buffers");
                    267:        minaddr = (vm_offset_t) buffers;
1.4       mw        268:        if ((bufpages / nbuf) >= btoc(MAXBSIZE)) {
                    269:                /* don't want to alloc more physical mem than needed */
                    270:                bufpages = btoc(MAXBSIZE) * nbuf;
                    271:        }
1.1       mw        272:        base = bufpages / nbuf;
                    273:        residual = bufpages % nbuf;
                    274:        for (i = 0; i < nbuf; i++) {
1.121     mhitch    275:                vm_size_t curbufsize;
                    276:                vm_offset_t curbuf;
                    277:                struct vm_page *pg;
                    278:
                    279:                /*
                    280:                 * Each buffer has MAXBSIZE bytes of VM space allocated.  Of
                    281:                 * that MAXBSIZE space, we allocate and map (base+1) pages
                    282:                 * for the first "residual" buffers, and then we allocate
                    283:                 * "base" pages for the rest.
                    284:                 */
                    285:                curbuf = (vm_offset_t) buffers + (i * MAXBSIZE);
1.141.2.1  bouyer    286:                curbufsize = NBPG * ((i < residual) ? (base+1) : base);
1.121     mhitch    287:
                    288:                while (curbufsize) {
1.134     chs       289:                        pg = uvm_pagealloc(NULL, 0, NULL, 0);
1.121     mhitch    290:                        if (pg == NULL)
                    291:                                panic("cpu_startup: not enough memory for "
                    292:                                    "buffer cache");
1.140     chs       293:                        pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
                    294:                                       VM_PROT_READ|VM_PROT_WRITE);
1.121     mhitch    295:                        curbuf += PAGE_SIZE;
                    296:                        curbufsize -= PAGE_SIZE;
                    297:                }
1.1       mw        298:        }
                    299:
                    300:        /*
                    301:         * Allocate a submap for exec arguments.  This map effectively
                    302:         * limits the number of processes exec'ing at any time.
                    303:         */
1.121     mhitch    304:        exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.137     thorpej   305:                                   16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
1.1       mw        306:
                    307:        /*
                    308:         * Allocate a submap for physio
                    309:         */
1.121     mhitch    310:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.137     thorpej   311:                                   VM_PHYS_SIZE, 0, FALSE, NULL);
1.1       mw        312:
                    313:        /*
1.86      thorpej   314:         * Finally, allocate mbuf cluster submap.
1.1       mw        315:         */
1.129     thorpej   316:        mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.137     thorpej   317:                                 nmbclusters * mclbytes, VM_MAP_INTRSAFE,
                    318:                                 FALSE, NULL);
1.1       mw        319:
                    320: #ifdef DEBUG
                    321:        pmapdebug = opmapdebug;
                    322: #endif
1.136     lukem     323:        format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
                    324:        printf("avail memory = %s\n", pbuf);
1.141.2.1  bouyer    325:        format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG);
1.136     lukem     326:        printf("using %d buffers containing %s of memory\n", nbuf, pbuf);
1.22      chopps    327:
1.29      chopps    328:        /*
                    329:         * display memory configuration passed from loadbsd
                    330:         */
                    331:        if (memlist->m_nseg > 0 && memlist->m_nseg < 16)
                    332:                for (i = 0; i < memlist->m_nseg; i++)
1.139     is        333:                        printf("memory segment %d at %08x size %08x\n", i,
1.29      chopps    334:                            memlist->m_seg[i].ms_start,
                    335:                            memlist->m_seg[i].ms_size);
1.66      is        336:
1.78      thorpej   337: #ifdef DEBUG_KERNEL_START
1.80      christos  338:        printf("calling initcpu...\n");
1.66      is        339: #endif
1.1       mw        340:        /*
                    341:         * Set up CPU-specific registers, cache, etc.
                    342:         */
                    343:        initcpu();
                    344:
1.73      is        345: #ifdef DEBUG_KERNEL_START
1.80      christos  346:        printf("survived initcpu...\n");
1.66      is        347: #endif
1.81      is        348:
1.1       mw        349:        /*
                    350:         * Set up buffers, so they can be used to read disk labels.
                    351:         */
                    352:        bufinit();
                    353:
1.73      is        354: #ifdef DEBUG_KERNEL_START
1.80      christos  355:        printf("survived bufinit...\n");
1.66      is        356: #endif
1.1       mw        357: }
                    358:
                    359: /*
                    360:  * Set registers on exec.
                    361:  */
                    362: void
1.96      mycroft   363: setregs(p, pack, stack)
1.1       mw        364:        register struct proc *p;
1.48      christos  365:        struct exec_package *pack;
1.1       mw        366:        u_long stack;
                    367: {
1.27      chopps    368:        struct frame *frame = (struct frame *)p->p_md.md_regs;
                    369:
1.99      mycroft   370:        frame->f_sr = PSL_USERSET;
1.48      christos  371:        frame->f_pc = pack->ep_entry & ~1;
1.97      mycroft   372:        frame->f_regs[D0] = 0;
                    373:        frame->f_regs[D1] = 0;
                    374:        frame->f_regs[D2] = 0;
                    375:        frame->f_regs[D3] = 0;
                    376:        frame->f_regs[D4] = 0;
                    377:        frame->f_regs[D5] = 0;
                    378:        frame->f_regs[D6] = 0;
                    379:        frame->f_regs[D7] = 0;
                    380:        frame->f_regs[A0] = 0;
                    381:        frame->f_regs[A1] = 0;
                    382:        frame->f_regs[A2] = (int)PS_STRINGS;
                    383:        frame->f_regs[A3] = 0;
                    384:        frame->f_regs[A4] = 0;
                    385:        frame->f_regs[A5] = 0;
                    386:        frame->f_regs[A6] = 0;
1.27      chopps    387:        frame->f_regs[SP] = stack;
                    388:
1.1       mw        389:        /* restore a null state frame */
                    390:        p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
1.94      is        391: #ifdef FPU_EMULATE
                    392:        if (!fputype)
                    393:                bzero(&p->p_addr->u_pcb.pcb_fpregs, sizeof(struct fpframe));
                    394:        else
                    395: #endif
                    396:                m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
1.1       mw        397: }
                    398:
1.23      chopps    399: /*
                    400:  * Info for CTL_HW
                    401:  */
                    402: char cpu_model[120];
1.81      is        403:
                    404: #if defined(M68060)
                    405: int m68060_pcr_init = 0x21;    /* make this patchable */
                    406: #endif
                    407:
1.23      chopps    408:
1.61      veego     409: void
1.1       mw        410: identifycpu()
                    411: {
1.3       mw        412:         /* there's alot of XXX in here... */
1.24      chopps    413:        char *mach, *mmu, *fpu;
1.3       mw        414:
1.70      is        415: #ifdef M68060
                    416:        char cpubuf[16];
                    417:        u_int32_t pcr;
                    418: #endif
1.72      is        419:
1.66      is        420: #ifdef DRACO
                    421:        char machbuf[16];
                    422:
                    423:        if (is_draco()) {
1.80      christos  424:                sprintf(machbuf, "DraCo rev.%d", is_draco());
1.66      is        425:                mach = machbuf;
                    426:        } else
                    427: #endif
1.23      chopps    428:        if (is_a4000())
                    429:                mach = "Amiga 4000";
                    430:        else if (is_a3000())
                    431:                mach = "Amiga 3000";
1.33      chopps    432:        else if (is_a1200())
                    433:                mach = "Amiga 1200";
1.3       mw        434:        else
1.23      chopps    435:                mach = "Amiga 500/2000";
1.1       mw        436:
1.31      chopps    437:        fpu = NULL;
1.72      is        438: #ifdef M68060
1.66      is        439:        if (machineid & AMIGA_68060) {
1.141.2.4! bouyer    440:                asm(".word 0x4e7a,0x0808; movl %%d0,%0" : "=d"(pcr) : : "d0");
1.80      christos  441:                sprintf(cpubuf, "68%s060 rev.%d",
1.70      is        442:                    pcr & 0x10000 ? "LC/EC" : "", (pcr>>8)&0xff);
                    443:                cpu_type = cpubuf;
1.66      is        444:                mmu = "/MMU";
1.94      is        445:                if (pcr & 2) {
                    446:                        fpu = "/FPU disabled";
                    447:                        fputype = FPU_NONE;
                    448:                } else if (m68060_pcr_init & 2){
                    449:                        fpu = "/FPU will be disabled";
                    450:                        fputype = FPU_NONE;
                    451:                } else  if (machineid & AMIGA_FPU40) {
                    452:                        fpu = "/FPU";
                    453:                        fputype = FPU_68040; /* XXX */
                    454:                }
1.72      is        455:        } else
                    456: #endif
                    457:        if (machineid & AMIGA_68040) {
1.5       mw        458:                cpu_type = "m68040";
1.23      chopps    459:                mmu = "/MMU";
1.24      chopps    460:                fpu = "/FPU";
1.81      is        461:                fputype = FPU_68040; /* XXX */
1.24      chopps    462:        } else if (machineid & AMIGA_68030) {
1.23      chopps    463:                cpu_type = "m68030";    /* XXX */
                    464:                mmu = "/MMU";
                    465:        } else {
                    466:                cpu_type = "m68020";
                    467:                mmu = " m68851 MMU";
                    468:        }
1.31      chopps    469:        if (fpu == NULL) {
1.52      chopps    470:                if (machineid & AMIGA_68882) {
1.24      chopps    471:                        fpu = " m68882 FPU";
1.52      chopps    472:                        fputype = FPU_68882;
                    473:                } else if (machineid & AMIGA_68881) {
1.24      chopps    474:                        fpu = " m68881 FPU";
1.52      chopps    475:                        fputype = FPU_68881;
                    476:                } else {
1.24      chopps    477:                        fpu = " no FPU";
1.52      chopps    478:                        fputype = FPU_NONE;
                    479:                }
1.24      chopps    480:        }
1.80      christos  481:        sprintf(cpu_model, "%s (%s CPU%s%s)", mach, cpu_type, mmu, fpu);
                    482:        printf("%s\n", cpu_model);
1.23      chopps    483: }
1.5       mw        484:
1.23      chopps    485: /*
                    486:  * machine dependent system variables.
                    487:  */
1.61      veego     488: int
1.23      chopps    489: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
                    490:        int *name;
                    491:        u_int namelen;
                    492:        void *oldp;
                    493:        size_t *oldlenp;
                    494:        void *newp;
                    495:        size_t newlen;
                    496:        struct proc *p;
                    497: {
                    498:        dev_t consdev;
1.1       mw        499:
1.23      chopps    500:        /* all sysctl names at this level are terminal */
                    501:        if (namelen != 1)
                    502:                return(ENOTDIR);               /* overloaded */
                    503:
                    504:        switch (name[0]) {
                    505:        case CPU_CONSDEV:
                    506:                if (cn_tab != NULL)
                    507:                        consdev = cn_tab->cn_dev;
1.5       mw        508:                else
1.23      chopps    509:                        consdev = NODEV;
                    510:                return(sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
                    511:                    sizeof(consdev)));
1.1       mw        512:        default:
1.23      chopps    513:                return(EOPNOTSUPP);
1.1       mw        514:        }
1.23      chopps    515:        /* NOTREACHED */
1.1       mw        516: }
1.4       mw        517:
1.3       mw        518: static int waittime = -1;
1.1       mw        519:
1.3       mw        520: void
                    521: bootsync(void)
1.1       mw        522: {
1.21      chopps    523:        if (waittime < 0) {
1.1       mw        524:                waittime = 0;
1.121     mhitch    525:                vfs_shutdown();
1.1       mw        526:                /*
                    527:                 * If we've been adjusting the clock, the todr
                    528:                 * will be out of synch; adjust it now.
                    529:                 */
                    530:                resettodr();
                    531:        }
1.3       mw        532: }
                    533:
1.63      veego     534:
1.27      chopps    535: void
1.85      gwr       536: cpu_reboot(howto, bootstr)
1.3       mw        537:        register int howto;
1.76      mrg       538:        char *bootstr;
1.3       mw        539: {
                    540:        /* take a snap shot before clobbering any registers */
                    541:        if (curproc)
1.61      veego     542:                savectx(&curproc->p_addr->u_pcb);
1.3       mw        543:
                    544:        boothowto = howto;
1.61      veego     545:        if ((howto & RB_NOSYNC) == 0)
1.3       mw        546:                bootsync();
1.63      veego     547:
                    548:        /* Disable interrupts. */
                    549:        spl7();
                    550:
                    551:        /* If rebooting and a dump is requested do it. */
                    552:        if (howto & RB_DUMP)
                    553:                dumpsys();
                    554:
1.61      veego     555:        if (howto & RB_HALT) {
1.101     veego     556:                printf("\n");
                    557:                printf("The operating system has halted.\n");
                    558:                printf("Please press any key to reboot.\n\n");
                    559:                cngetc();
1.1       mw        560:        }
1.63      veego     561:
1.101     veego     562:        printf("rebooting...\n");
                    563:        DELAY(1000000);
1.63      veego     564:        doboot();
1.1       mw        565:        /*NOTREACHED*/
                    566: }
1.63      veego     567:
1.1       mw        568:
1.3       mw        569: unsigned       dumpmag = 0x8fca0101;   /* magic number for savecore */
1.1       mw        570: int    dumpsize = 0;           /* also for savecore */
                    571: long   dumplo = 0;
1.68      mhitch    572: cpu_kcore_hdr_t cpu_kcore_hdr;
1.1       mw        573:
1.61      veego     574: void
1.85      gwr       575: cpu_dumpconf()
1.1       mw        576: {
1.89      thorpej   577:        cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
                    578:        struct m68k_kcore_hdr *m = &h->un._m68k;
1.1       mw        579:        int nblks;
1.68      mhitch    580:        int i;
                    581:        extern u_int Sysseg_pa;
1.115     mhitch    582:        extern int end[];
1.89      thorpej   583:
                    584:        bzero(&cpu_kcore_hdr, sizeof(cpu_kcore_hdr));
                    585:
                    586:        /*
                    587:         * Intitialize the `dispatcher' portion of the header.
                    588:         */
                    589:        strcpy(h->name, machine);
                    590:        h->page_size = NBPG;
                    591:        h->kernbase = KERNBASE;
                    592:
                    593:        /*
                    594:         * Fill in information about our MMU configuration.
                    595:         */
                    596:        m->mmutype      = mmutype;
                    597:        m->sg_v         = SG_V;
                    598:        m->sg_frame     = SG_FRAME;
                    599:        m->sg_ishift    = SG_ISHIFT;
                    600:        m->sg_pmask     = SG_PMASK;
                    601:        m->sg40_shift1  = SG4_SHIFT1;
                    602:        m->sg40_mask2   = SG4_MASK2;
                    603:        m->sg40_shift2  = SG4_SHIFT2;
                    604:        m->sg40_mask3   = SG4_MASK3;
                    605:        m->sg40_shift3  = SG4_SHIFT3;
                    606:        m->sg40_addr1   = SG4_ADDR1;
                    607:        m->sg40_addr2   = SG4_ADDR2;
                    608:        m->pg_v         = PG_V;
                    609:        m->pg_frame     = PG_FRAME;
                    610:
                    611:        /*
                    612:         * Initialize the pointer to the kernel segment table.
                    613:         */
                    614:        m->sysseg_pa = Sysseg_pa;
                    615:
                    616:        /*
                    617:         * Initialize relocation value such that:
                    618:         *
                    619:         *      pa = (va - KERNBASE) + reloc
                    620:         */
                    621:        m->reloc = lowram;
                    622:
                    623:        /*
                    624:         * Define the end of the relocatable range.
                    625:         */
1.115     mhitch    626:        m->relocend = (u_int32_t)&end;
1.1       mw        627:
1.68      mhitch    628:        /* XXX new corefile format, single segment + chipmem */
1.1       mw        629:        dumpsize = physmem;
1.89      thorpej   630:        m->ram_segs[0].start = lowram;
                    631:        m->ram_segs[0].size  = ctob(physmem);
1.68      mhitch    632:        for (i = 0; i < memlist->m_nseg; i++) {
                    633:                if ((memlist->m_seg[i].ms_attrib & MEMF_CHIP) == 0)
                    634:                        continue;
                    635:                dumpsize += btoc(memlist->m_seg[i].ms_size);
1.89      thorpej   636:                m->ram_segs[1].start = 0;
                    637:                m->ram_segs[1].size  = memlist->m_seg[i].ms_size;
1.68      mhitch    638:                break;
                    639:        }
1.1       mw        640:        if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
                    641:                nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
                    642:                if (dumpsize > btoc(dbtob(nblks - dumplo)))
                    643:                        dumpsize = btoc(dbtob(nblks - dumplo));
                    644:                else if (dumplo == 0)
1.68      mhitch    645:                        dumplo = nblks - btodb(ctob(dumpsize));
1.1       mw        646:        }
1.68      mhitch    647:        --dumplo;       /* XXX assume header fits in one block */
1.1       mw        648:        /*
1.141.2.1  bouyer    649:         * Don't dump on the first NBPG (why NBPG?)
1.1       mw        650:         * in case the dump device includes a disk label.
                    651:         */
1.141.2.1  bouyer    652:        if (dumplo < btodb(NBPG))
                    653:                dumplo = btodb(NBPG);
1.1       mw        654: }
                    655:
                    656: /*
                    657:  * Doadump comes here after turning off memory management and
                    658:  * getting on the dump stack, either when called above, or by
                    659:  * the auto-restart code.
                    660:  */
1.57      chopps    661: #define BYTES_PER_DUMP MAXPHYS /* Must be a multiple of pagesize XXX small */
1.55      chopps    662: static vm_offset_t dumpspace;
                    663:
                    664: vm_offset_t
                    665: reserve_dumppages(p)
                    666:        vm_offset_t p;
                    667: {
                    668:        dumpspace = p;
                    669:        return (p + BYTES_PER_DUMP);
                    670: }
                    671:
1.61      veego     672: void
1.1       mw        673: dumpsys()
                    674: {
1.68      mhitch    675:        unsigned bytes, i, n, seg;
1.55      chopps    676:        int     maddr, psize;
                    677:        daddr_t blkno;
                    678:        int     (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
                    679:        int     error = 0;
1.68      mhitch    680:        kcore_seg_t *kseg_p;
                    681:        cpu_kcore_hdr_t *chdr_p;
                    682:        char    dump_hdr[dbtob(1)];     /* XXX assume hdr fits in 1 block */
1.1       mw        683:
                    684:        if (dumpdev == NODEV)
                    685:                return;
                    686:        /*
                    687:         * For dumps during autoconfiguration,
                    688:         * if dump device has already configured...
                    689:         */
                    690:        if (dumpsize == 0)
1.85      gwr       691:                cpu_dumpconf();
1.108     mycroft   692:        if (dumplo <= 0) {
                    693:                printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
                    694:                    minor(dumpdev));
1.1       mw        695:                return;
1.108     mycroft   696:        }
                    697:        printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
                    698:            minor(dumpdev), dumplo);
1.55      chopps    699:
1.108     mycroft   700:        psize = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
1.80      christos  701:        printf("dump ");
1.55      chopps    702:        if (psize == -1) {
1.80      christos  703:                printf("area unavailable.\n");
1.55      chopps    704:                return;
                    705:        }
1.68      mhitch    706:        kseg_p = (kcore_seg_t *)dump_hdr;
                    707:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
                    708:        bzero(dump_hdr, sizeof(dump_hdr));
                    709:
                    710:        /*
                    711:         * Generate a segment header
                    712:         */
                    713:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
                    714:        kseg_p->c_size = dbtob(1) - ALIGN(sizeof(*kseg_p));
                    715:
                    716:        /*
                    717:         * Add the md header
                    718:         */
                    719:
                    720:        *chdr_p = cpu_kcore_hdr;
                    721:
1.55      chopps    722:        bytes = ctob(dumpsize);
1.89      thorpej   723:        maddr = cpu_kcore_hdr.un._m68k.ram_segs[0].start;
1.68      mhitch    724:        seg = 0;
1.55      chopps    725:        blkno = dumplo;
                    726:        dump = bdevsw[major(dumpdev)].d_dump;
1.68      mhitch    727:        error = (*dump) (dumpdev, blkno++, (caddr_t)dump_hdr, dbtob(1));
                    728:        for (i = 0; i < bytes && error == 0; i += n) {
1.55      chopps    729:                /* Print out how many MBs we have to go. */
                    730:                n = bytes - i;
                    731:                if (n && (n % (1024 * 1024)) == 0)
1.80      christos  732:                        printf("%d ", n / (1024 * 1024));
1.55      chopps    733:
                    734:                /* Limit size for next transfer. */
                    735:                if (n > BYTES_PER_DUMP)
                    736:                        n = BYTES_PER_DUMP;
                    737:
1.68      mhitch    738:                if (maddr == 0) {       /* XXX kvtop chokes on this */
                    739:                        maddr += NBPG;
                    740:                        n -= NBPG;
                    741:                        i += NBPG;
                    742:                        ++blkno;        /* XXX skip physical page 0 */
                    743:                }
1.55      chopps    744:                (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
                    745:                error = (*dump) (dumpdev, blkno, (caddr_t) dumpspace, n);
                    746:                if (error)
                    747:                        break;
                    748:                maddr += n;
                    749:                blkno += btodb(n);      /* XXX? */
1.89      thorpej   750:                if (maddr >= (cpu_kcore_hdr.un._m68k.ram_segs[seg].start +
                    751:                    cpu_kcore_hdr.un._m68k.ram_segs[seg].size)) {
1.68      mhitch    752:                        ++seg;
1.89      thorpej   753:                        maddr = cpu_kcore_hdr.un._m68k.ram_segs[seg].start;
                    754:                        if (cpu_kcore_hdr.un._m68k.ram_segs[seg].size == 0)
1.68      mhitch    755:                                break;
                    756:                }
1.55      chopps    757:        }
                    758:
                    759:        switch (error) {
1.1       mw        760:
                    761:        case ENXIO:
1.80      christos  762:                printf("device bad\n");
1.1       mw        763:                break;
                    764:
                    765:        case EFAULT:
1.80      christos  766:                printf("device not ready\n");
1.1       mw        767:                break;
                    768:
                    769:        case EINVAL:
1.80      christos  770:                printf("area improper\n");
1.1       mw        771:                break;
                    772:
                    773:        case EIO:
1.80      christos  774:                printf("i/o error\n");
1.1       mw        775:                break;
                    776:
                    777:        default:
1.80      christos  778:                printf("succeeded\n");
1.1       mw        779:                break;
                    780:        }
1.80      christos  781:        printf("\n\n");
1.55      chopps    782:        delay(5000000);         /* 5 seconds */
1.1       mw        783: }
                    784:
                    785: /*
                    786:  * Return the best possible estimate of the time in the timeval
                    787:  * to which tvp points.  We do this by returning the current time
                    788:  * plus the amount of time since the last clock interrupt (clock.c:clkread).
                    789:  *
                    790:  * Check that this time is no less than any previously-reported time,
                    791:  * which could happen around the time of a clock adjustment.  Just for fun,
                    792:  * we guarantee that the time will be greater than the value obtained by a
                    793:  * previous call.
                    794:  */
1.43      chopps    795: void
1.1       mw        796: microtime(tvp)
                    797:        register struct timeval *tvp;
                    798: {
1.45      chopps    799:        int s = spl7();
1.1       mw        800:        static struct timeval lasttime;
                    801:
                    802:        *tvp = time;
                    803:        tvp->tv_usec += clkread();
1.141.2.1  bouyer    804:        while (tvp->tv_usec >= 1000000) {
1.1       mw        805:                tvp->tv_sec++;
                    806:                tvp->tv_usec -= 1000000;
                    807:        }
                    808:        if (tvp->tv_sec == lasttime.tv_sec &&
                    809:            tvp->tv_usec <= lasttime.tv_usec &&
1.141.2.1  bouyer    810:            (tvp->tv_usec = lasttime.tv_usec + 1) >= 1000000) {
1.1       mw        811:                tvp->tv_sec++;
                    812:                tvp->tv_usec -= 1000000;
                    813:        }
                    814:        lasttime = *tvp;
                    815:        splx(s);
                    816: }
                    817:
1.61      veego     818: void
1.1       mw        819: initcpu()
                    820: {
1.93      is        821:        typedef void trapfun __P((void));
                    822:
1.67      is        823:        /* XXX should init '40 vecs here, too */
1.94      is        824: #if defined(M68060) || defined(M68040) || defined(DRACO) || defined(FPU_EMULATE)
1.93      is        825:        extern trapfun *vectab[256];
1.70      is        826: #endif
1.66      is        827:
1.90      is        828: #if defined(M68060) || defined(M68040)
1.93      is        829:        extern trapfun addrerr4060;
1.90      is        830: #endif
                    831:
1.72      is        832: #ifdef M68060
1.93      is        833:        extern trapfun buserr60;
1.69      is        834: #if defined(M060SP)
1.82      is        835:        /*extern u_int8_t I_CALL_TOP[];*/
1.93      is        836:        extern trapfun intemu60, fpiemu60, fpdemu60, fpeaemu60;
1.66      is        837:        extern u_int8_t FP_CALL_TOP[];
1.69      is        838: #else
1.93      is        839:        extern trapfun illinst;
1.72      is        840: #endif
1.93      is        841:        extern trapfun fpfault;
1.69      is        842: #endif
1.66      is        843:
1.90      is        844: #ifdef M68040
1.93      is        845:        extern trapfun buserr40;
1.90      is        846: #endif
                    847:
1.70      is        848: #ifdef DRACO
1.93      is        849:        extern trapfun DraCoIntr, DraCoLev1intr, DraCoLev2intr;
1.77      is        850:        u_char dracorev;
1.70      is        851: #endif
                    852:
1.94      is        853: #ifdef FPU_EMULATE
                    854:        extern trapfun fpemuli;
                    855: #endif
                    856:
1.70      is        857: #ifdef M68060
1.66      is        858:        if (machineid & AMIGA_68060) {
1.94      is        859:                if (machineid & AMIGA_FPU40 && m68060_pcr_init & 2) {
                    860:                        /*
                    861:                         * in this case, we're about to switch the FPU off;
                    862:                         * do a FNOP to avoid stray FP traps later
                    863:                         */
                    864:                        __asm("fnop");
                    865:                        /* ... and mark FPU as absent for identifyfpu() */
                    866:                        machineid &= ~(AMIGA_FPU40|AMIGA_68882|AMIGA_68881);
                    867:                }
1.141.2.4! bouyer    868:                asm volatile ("movl %0,%%d0; .word 0x4e7b,0x0808" : :
1.66      is        869:                        "d"(m68060_pcr_init):"d0" );
1.90      is        870:
                    871:                /* bus/addrerr vectors */
1.93      is        872:                vectab[2] = buserr60;
                    873:                vectab[3] = addrerr4060;
1.66      is        874: #if defined(M060SP)
                    875:
                    876:                /* integer support */
1.93      is        877:                vectab[61] = intemu60/*(trapfun *)&I_CALL_TOP[128 + 0x00]*/;
1.66      is        878:
                    879:                /* floating point support */
1.81      is        880:                /*
                    881:                 * XXX maybe we really should run-time check for the
                    882:                 * stack frame format here:
                    883:                 */
1.93      is        884:                vectab[11] = fpiemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x30]*/;
1.81      is        885:
1.93      is        886:                vectab[55] = fpdemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x38]*/;
                    887:                vectab[60] = fpeaemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x40]*/;
1.66      is        888:
1.93      is        889:                vectab[54] = (trapfun *)&FP_CALL_TOP[128 + 0x00];
                    890:                vectab[52] = (trapfun *)&FP_CALL_TOP[128 + 0x08];
                    891:                vectab[53] = (trapfun *)&FP_CALL_TOP[128 + 0x10];
                    892:                vectab[51] = (trapfun *)&FP_CALL_TOP[128 + 0x18];
                    893:                vectab[50] = (trapfun *)&FP_CALL_TOP[128 + 0x20];
                    894:                vectab[49] = (trapfun *)&FP_CALL_TOP[128 + 0x28];
1.66      is        895:
                    896: #else
1.93      is        897:                vectab[61] = illinst;
1.66      is        898: #endif
1.93      is        899:                vectab[48] = fpfault;
1.66      is        900:        }
                    901: #endif
1.70      is        902:
1.81      is        903: /*
                    904:  * Vector initialization for special motherboards
                    905:  */
1.90      is        906: #ifdef M68040
                    907: #ifdef M68060
                    908:        else
                    909: #endif
                    910:        if (machineid & AMIGA_68040) {
                    911:                /* addrerr vector */
1.93      is        912:                vectab[2] = buserr40;
                    913:                vectab[3] = addrerr4060;
1.90      is        914:        }
                    915: #endif
1.94      is        916:
                    917: #ifdef FPU_EMULATE
                    918:        if (!(machineid & (AMIGA_68881|AMIGA_68882|AMIGA_FPU40))) {
                    919:                vectab[11] = fpemuli;
                    920:                printf("FPU software emulation initialized.\n");
                    921:        }
                    922: #endif
                    923:
                    924: /*
                    925:  * Vector initialization for special motherboards
                    926:  */
1.81      is        927:
1.70      is        928: #ifdef DRACO
1.77      is        929:        dracorev = is_draco();
                    930:        if (dracorev) {
                    931:                if (dracorev >= 4) {
1.93      is        932:                        vectab[24+1] = DraCoLev1intr;
                    933:                        vectab[24+2] = DraCoIntr;
1.77      is        934:                } else {
1.93      is        935:                        vectab[24+1] = DraCoIntr;
                    936:                        vectab[24+2] = DraCoLev2intr;
1.77      is        937:                }
1.93      is        938:                vectab[24+3] = DraCoIntr;
                    939:                vectab[24+4] = DraCoIntr;
                    940:                vectab[24+5] = DraCoIntr;
                    941:                vectab[24+6] = DraCoIntr;
1.70      is        942:        }
                    943: #endif
1.1       mw        944: }
                    945:
1.61      veego     946: void
1.1       mw        947: straytrap(pc, evec)
                    948:        int pc;
                    949:        u_short evec;
                    950: {
1.80      christos  951:        printf("unexpected trap format %x (vector offset %x) from %x\n",
1.66      is        952:               evec>>12, evec & 0xFFF, pc);
1.42      chopps    953: /*XXX*/        panic("straytrap");
1.1       mw        954: }
                    955:
                    956: int    *nofault;
                    957:
1.61      veego     958: int
1.1       mw        959: badaddr(addr)
                    960:        register caddr_t addr;
                    961: {
                    962:        register int i;
                    963:        label_t faultbuf;
                    964:
                    965: #ifdef lint
                    966:        i = *addr; if (i) return(0);
                    967: #endif
                    968:        nofault = (int *) &faultbuf;
                    969:        if (setjmp((label_t *)nofault)) {
                    970:                nofault = (int *) 0;
                    971:                return(1);
                    972:        }
                    973:        i = *(volatile short *)addr;
                    974:        nofault = (int *) 0;
                    975:        return(0);
                    976: }
                    977:
1.61      veego     978: int
1.1       mw        979: badbaddr(addr)
                    980:        register caddr_t addr;
                    981: {
                    982:        register int i;
                    983:        label_t faultbuf;
                    984:
                    985: #ifdef lint
                    986:        i = *addr; if (i) return(0);
                    987: #endif
                    988:        nofault = (int *) &faultbuf;
                    989:        if (setjmp((label_t *)nofault)) {
                    990:                nofault = (int *) 0;
                    991:                return(1);
                    992:        }
                    993:        i = *(volatile char *)addr;
                    994:        nofault = (int *) 0;
                    995:        return(0);
                    996: }
                    997:
1.61      veego     998: static void
1.1       mw        999: netintr()
                   1000: {
1.141.2.1  bouyer   1001:
                   1002: #define DONETISR(bit, fn) do {         \
                   1003:        if (netisr & (1 << bit)) {      \
                   1004:                netisr &= ~(1 << bit);  \
                   1005:                fn();                   \
                   1006:        }                               \
                   1007: } while (0)
                   1008:
                   1009: #include <net/netisr_dispatch.h>
                   1010:
                   1011: #undef DONETISR
1.1       mw       1012: }
                   1013:
1.3       mw       1014:
1.31      chopps   1015: /*
                   1016:  * this is a handy package to have asynchronously executed
                   1017:  * function calls executed at very low interrupt priority.
                   1018:  * Example for use is keyboard repeat, where the repeat
                   1019:  * handler running at splclock() triggers such a (hardware
                   1020:  * aided) software interrupt.
                   1021:  * Note: the installed functions are currently called in a
                   1022:  * LIFO fashion, might want to change this to FIFO
                   1023:  * later.
                   1024:  */
1.3       mw       1025: struct si_callback {
1.31      chopps   1026:        struct si_callback *next;
                   1027:        void (*function) __P((void *rock1, void *rock2));
                   1028:        void *rock1, *rock2;
1.3       mw       1029: };
1.31      chopps   1030: static struct si_callback *si_callbacks;
1.42      chopps   1031: static struct si_callback *si_free;
                   1032: #ifdef DIAGNOSTIC
                   1033: static int ncb;                /* number of callback blocks allocated */
                   1034: static int ncbd;       /* number of callback blocks dynamically allocated */
                   1035: #endif
                   1036:
1.95      is       1037: /*
                   1038:  * these are __GENERIC_SOFT_INTERRUPT wrappers; will be replaced
                   1039:  * once by the real thing once all drivers are converted.
                   1040:  *
                   1041:  * to help performance for converted drivers, the YYY_sicallback() function
                   1042:  * family can be implemented in terms of softintr_XXX() as an intermediate
                   1043:  * measure.
                   1044:  */
                   1045:
                   1046: static void
                   1047: _softintr_callit(rock1, rock2)
                   1048:        void *rock1, *rock2;
                   1049: {
                   1050:        (*(void (*)(void *))rock1)(rock2);
                   1051: }
                   1052:
                   1053: void *
                   1054: softintr_establish(ipl, func, arg)
                   1055:        int ipl;
                   1056:        void func __P((void *));
                   1057:        void *arg;
                   1058: {
                   1059:        struct si_callback *si;
                   1060:
                   1061:        (void)ipl;
                   1062:
                   1063:        si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
                   1064:        if (si == NULL)
                   1065:                return (si);
                   1066:
                   1067:        si->function = (void *)0;
                   1068:        si->rock1 = (void *)func;
                   1069:        si->rock2 = arg;
                   1070:
                   1071:        alloc_sicallback();
                   1072:        return ((void *)si);
                   1073: }
                   1074:
1.127     is       1075: void
                   1076: softintr_disestablish(hook)
                   1077:        void *hook;
                   1078: {
                   1079:        /*
                   1080:         * XXX currently, there is a memory leak here; we cant free the
                   1081:         * sicallback structure.
                   1082:         * this will be automatically repaired once we rewirte the soft
                   1083:         * interupt functions.
                   1084:         */
                   1085:
                   1086:        free(hook, M_TEMP);
                   1087: }
1.95      is       1088:
1.42      chopps   1089: void
                   1090: alloc_sicallback()
                   1091: {
                   1092:        struct si_callback *si;
                   1093:        int s;
                   1094:
                   1095:        si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
                   1096:        if (si == NULL)
                   1097:                return;
                   1098:        s = splhigh();
                   1099:        si->next = si_free;
                   1100:        si_free = si;
                   1101:        splx(s);
                   1102: #ifdef DIAGNOSTIC
                   1103:        ++ncb;
                   1104: #endif
1.95      is       1105: }
                   1106:
                   1107: void
                   1108: softintr_schedule(vsi)
                   1109:        void *vsi;
                   1110: {
                   1111:        struct si_callback *si;
                   1112:        si = vsi;
                   1113:
                   1114:        add_sicallback(_softintr_callit, si->rock1, si->rock2);
1.42      chopps   1115: }
1.3       mw       1116:
                   1117: void
                   1118: add_sicallback (function, rock1, rock2)
1.31      chopps   1119:        void (*function) __P((void *rock1, void *rock2));
                   1120:        void *rock1, *rock2;
1.3       mw       1121: {
1.31      chopps   1122:        struct si_callback *si;
                   1123:        int s;
1.3       mw       1124:
1.31      chopps   1125:        /*
                   1126:         * this function may be called from high-priority interrupt handlers.
                   1127:         * We may NOT block for  memory-allocation in here!.
                   1128:         */
1.42      chopps   1129:        s = splhigh();
                   1130:        si = si_free;
                   1131:        if (si != NULL)
                   1132:                si_free = si->next;
                   1133:        splx(s);
                   1134:
                   1135:        if (si == NULL) {
                   1136:                si = (struct si_callback *)malloc(sizeof(*si), M_TEMP, M_NOWAIT);
                   1137: #ifdef DIAGNOSTIC
                   1138:                if (si)
                   1139:                        ++ncbd;         /* count # dynamically allocated */
                   1140: #endif
1.3       mw       1141:
1.42      chopps   1142:                if (!si)
                   1143:                        return;
                   1144:        }
1.3       mw       1145:
1.31      chopps   1146:        si->function = function;
                   1147:        si->rock1 = rock1;
                   1148:        si->rock2 = rock2;
1.3       mw       1149:
1.31      chopps   1150:        s = splhigh();
                   1151:        si->next = si_callbacks;
                   1152:        si_callbacks = si;
                   1153:        splx(s);
1.3       mw       1154:
1.31      chopps   1155:        /*
1.45      chopps   1156:         * Cause a software interrupt (spl1). This interrupt might
1.31      chopps   1157:         * happen immediately, or after returning to a safe enough level.
                   1158:         */
1.45      chopps   1159:        setsoftcback();
1.3       mw       1160: }
                   1161:
                   1162:
                   1163: void
1.31      chopps   1164: rem_sicallback(function)
                   1165:        void (*function) __P((void *rock1, void *rock2));
1.3       mw       1166: {
1.31      chopps   1167:        struct si_callback *si, *psi, *nsi;
                   1168:        int s;
1.3       mw       1169:
1.31      chopps   1170:        s = splhigh();
                   1171:        for (psi = 0, si = si_callbacks; si; ) {
                   1172:                nsi = si->next;
1.3       mw       1173:
1.31      chopps   1174:                if (si->function != function)
                   1175:                        psi = si;
                   1176:                else {
1.42      chopps   1177: /*                     free(si, M_TEMP); */
                   1178:                        si->next = si_free;
                   1179:                        si_free = si;
1.31      chopps   1180:                        if (psi)
                   1181:                                psi->next = nsi;
                   1182:                        else
                   1183:                                si_callbacks = nsi;
                   1184:                }
                   1185:                si = nsi;
1.3       mw       1186:        }
1.31      chopps   1187:        splx(s);
1.3       mw       1188: }
                   1189:
                   1190: /* purge the list */
                   1191: static void
1.31      chopps   1192: call_sicallbacks()
1.3       mw       1193: {
1.31      chopps   1194:        struct si_callback *si;
                   1195:        int s;
1.42      chopps   1196:        void *rock1, *rock2;
                   1197:        void (*function) __P((void *, void *));
1.3       mw       1198:
1.31      chopps   1199:        do {
                   1200:                s = splhigh ();
1.61      veego    1201:                if ((si = si_callbacks) != 0)
1.31      chopps   1202:                        si_callbacks = si->next;
                   1203:                splx(s);
                   1204:
                   1205:                if (si) {
1.42      chopps   1206:                        function = si->function;
                   1207:                        rock1 = si->rock1;
                   1208:                        rock2 = si->rock2;
                   1209: /*                     si->function(si->rock1, si->rock2); */
                   1210: /*                     free(si, M_TEMP); */
                   1211:                        s = splhigh ();
                   1212:                        si->next = si_free;
                   1213:                        si_free = si;
                   1214:                        splx(s);
                   1215:                        function (rock1, rock2);
1.31      chopps   1216:                }
                   1217:        } while (si);
1.42      chopps   1218: #ifdef DIAGNOSTIC
                   1219:        if (ncbd) {
1.44      chopps   1220:                ncb += ncbd;
1.80      christos 1221:                printf("call_sicallback: %d more dynamic structures %d total\n",
1.42      chopps   1222:                    ncbd, ncb);
                   1223:                ncbd = 0;
                   1224:        }
                   1225: #endif
1.3       mw       1226: }
                   1227:
1.45      chopps   1228: struct isr *isr_ports;
1.66      is       1229: #ifdef DRACO
                   1230: struct isr *isr_slot3;
1.81      is       1231: struct isr *isr_supio;
1.66      is       1232: #endif
1.45      chopps   1233: struct isr *isr_exter;
                   1234:
                   1235: void
                   1236: add_isr(isr)
                   1237:        struct isr *isr;
                   1238: {
                   1239:        struct isr **p, *q;
                   1240:
1.66      is       1241: #ifdef DRACO
                   1242:        switch (isr->isr_ipl) {
                   1243:        case 2:
                   1244:                p = &isr_ports;
                   1245:                break;
                   1246:        case 3:
                   1247:                p = &isr_slot3;
                   1248:                break;
1.81      is       1249:        case 5:
                   1250:                p = &isr_supio;
                   1251:                break;
1.70      is       1252:        default:        /* was case 6:; make gcc -Wall quiet */
1.66      is       1253:                p = &isr_exter;
                   1254:                break;
                   1255:        }
                   1256: #else
1.45      chopps   1257:        p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter;
1.66      is       1258: #endif
1.45      chopps   1259:        while ((q = *p) != NULL)
                   1260:                p = &q->isr_forw;
                   1261:        isr->isr_forw = NULL;
                   1262:        *p = isr;
                   1263:        /* enable interrupt */
1.66      is       1264: #ifdef DRACO
                   1265:        if (is_draco())
1.81      is       1266:                switch(isr->isr_ipl) {
                   1267:                        case 6:
1.122     is       1268:                                single_inst_bset_b(*draco_intena, DRIRQ_INT6);
1.81      is       1269:                                break;
                   1270:                        case 2:
1.122     is       1271:                                single_inst_bset_b(*draco_intena, DRIRQ_INT2);
1.81      is       1272:                                break;
                   1273:                        default:
                   1274:                                break;
                   1275:                }
1.66      is       1276:        else
                   1277: #endif
                   1278:                custom.intena = isr->isr_ipl == 2 ?
                   1279:                    INTF_SETCLR | INTF_PORTS :
                   1280:                    INTF_SETCLR | INTF_EXTER;
1.45      chopps   1281: }
                   1282:
                   1283: void
                   1284: remove_isr(isr)
                   1285:        struct isr *isr;
                   1286: {
                   1287:        struct isr **p, *q;
                   1288:
1.66      is       1289: #ifdef DRACO
                   1290:        switch (isr->isr_ipl) {
                   1291:        case 2:
                   1292:                p = &isr_ports;
                   1293:                break;
                   1294:        case 3:
                   1295:                p = &isr_slot3;
                   1296:                break;
1.81      is       1297:        case 5:
                   1298:                p = &isr_supio;
                   1299:                break;
1.70      is       1300:        default:        /* XXX to make gcc -Wall quiet, was 6: */
1.66      is       1301:                p = &isr_exter;
                   1302:                break;
                   1303:        }
                   1304: #else
1.45      chopps   1305:        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66      is       1306: #endif
                   1307:
1.45      chopps   1308:        while ((q = *p) != NULL && q != isr)
                   1309:                p = &q->isr_forw;
                   1310:        if (q)
                   1311:                *p = q->isr_forw;
                   1312:        else
                   1313:                panic("remove_isr: handler not registered");
                   1314:        /* disable interrupt if no more handlers */
1.66      is       1315: #ifdef DRACO
                   1316:        switch (isr->isr_ipl) {
                   1317:        case 2:
                   1318:                p = &isr_ports;
                   1319:                break;
                   1320:        case 3:
                   1321:                p = &isr_slot3;
                   1322:                break;
1.81      is       1323:        case 5:
                   1324:                p = &isr_supio;
                   1325:                break;
1.66      is       1326:        case 6:
                   1327:                p = &isr_exter;
                   1328:                break;
                   1329:        }
                   1330: #else
1.45      chopps   1331:        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66      is       1332: #endif
1.128     is       1333:        if (*p == NULL) {
1.66      is       1334: #ifdef DRACO
1.81      is       1335:                if (is_draco()) {
                   1336:                        switch(isr->isr_ipl) {
                   1337:                                case 2:
1.122     is       1338:                                        single_inst_bclr_b(*draco_intena,
                   1339:                                            DRIRQ_INT2);
1.81      is       1340:                                        break;
                   1341:                                case 6:
1.122     is       1342:                                        single_inst_bclr_b(*draco_intena,
                   1343:                                            DRIRQ_INT6);
1.81      is       1344:                                        break;
                   1345:                                default:
                   1346:                                        break;
                   1347:                        }
                   1348:                } else
1.66      is       1349: #endif
                   1350:                        custom.intena = isr->isr_ipl == 6 ?
                   1351:                            INTF_EXTER : INTF_PORTS;
1.128     is       1352:        }
1.45      chopps   1353: }
                   1354:
1.61      veego    1355: void
1.1       mw       1356: intrhand(sr)
                   1357:        int sr;
                   1358: {
1.22      chopps   1359:        register unsigned int ipl;
                   1360:        register unsigned short ireq;
1.45      chopps   1361:        register struct isr **p, *q;
1.1       mw       1362:
1.22      chopps   1363:        ipl = (sr >> 8) & 7;
1.66      is       1364: #ifdef REALLYDEBUG
1.80      christos 1365:        printf("intrhand: got int. %d\n", ipl);
1.66      is       1366: #endif
                   1367: #ifdef DRACO
                   1368:        if (is_draco())
                   1369:                ireq = ((ipl == 1)  && (*draco_intfrc & DRIRQ_SOFT) ?
                   1370:                    INTF_SOFTINT : 0);
                   1371:        else
                   1372: #endif
                   1373:                ireq = custom.intreqr;
1.1       mw       1374:
1.22      chopps   1375:        switch (ipl) {
                   1376:        case 1:
1.66      is       1377: #ifdef DRACO
                   1378:                if (is_draco() && (draco_ioct->io_status & DRSTAT_KBDRECV))
                   1379:                        drkbdintr();
                   1380: #endif
1.22      chopps   1381:                if (ireq & INTF_TBE) {
                   1382: #if NSER > 0
                   1383:                        ser_outintr();
                   1384: #else
                   1385:                        custom.intreq = INTF_TBE;
                   1386: #endif
                   1387:                }
                   1388:
                   1389:                if (ireq & INTF_DSKBLK) {
1.17      chopps   1390: #if NFD > 0
1.22      chopps   1391:                        fdintr(0);
1.17      chopps   1392: #endif
1.22      chopps   1393:                        custom.intreq = INTF_DSKBLK;
                   1394:                }
                   1395:                if (ireq & INTF_SOFTINT) {
1.61      veego    1396:                        unsigned char ssir_active;
                   1397:                        int s;
                   1398:
1.22      chopps   1399:                        /*
1.36      chopps   1400:                         * first clear the softint-bit
1.45      chopps   1401:                         * then process all classes of softints.
1.36      chopps   1402:                         * this order is dicated by the nature of
                   1403:                         * software interrupts.  The other order
1.61      veego    1404:                         * allows software interrupts to be missed.
                   1405:                         * Also copy and clear ssir to prevent
                   1406:                         * interrupt loss.
1.22      chopps   1407:                         */
1.45      chopps   1408:                        clrsoftint();
1.61      veego    1409:                        s = splhigh();
                   1410:                        ssir_active = ssir;
1.141.2.3  bouyer   1411:                        siroff(SIR_NET | SIR_CBACK);
1.61      veego    1412:                        splx(s);
                   1413:                        if (ssir_active & SIR_NET) {
1.66      is       1414: #ifdef REALLYDEBUG
1.80      christos 1415:                                printf("calling netintr\n");
1.66      is       1416: #endif
1.121     mhitch   1417:                                uvmexp.softs++;
1.45      chopps   1418:                                netintr();
                   1419:                        }
1.61      veego    1420:                        if (ssir_active & SIR_CBACK) {
1.66      is       1421: #ifdef REALLYDEBUG
1.80      christos 1422:                                printf("calling softcallbacks\n");
1.66      is       1423: #endif
1.121     mhitch   1424:                                uvmexp.softs++;
1.45      chopps   1425:                                call_sicallbacks();
                   1426:                        }
1.22      chopps   1427:                }
                   1428:                break;
                   1429:
                   1430:        case 2:
1.45      chopps   1431:                p = &isr_ports;
                   1432:                while ((q = *p) != NULL) {
                   1433:                        if ((q->isr_intr)(q->isr_arg))
                   1434:                                break;
                   1435:                        p = &q->isr_forw;
                   1436:                }
                   1437:                if (q == NULL)
                   1438:                        ciaa_intr ();
1.66      is       1439: #ifdef DRACO
                   1440:                if (is_draco())
1.122     is       1441:                        single_inst_bclr_b(*draco_intpen, DRIRQ_INT2);
1.66      is       1442:                else
                   1443: #endif
                   1444:                        custom.intreq = INTF_PORTS;
1.104     is       1445:
1.22      chopps   1446:                break;
1.104     is       1447:
                   1448: #ifdef DRACO
                   1449:        /* only handled here for DraCo */
                   1450:        case 6:
                   1451:                p = &isr_exter;
                   1452:                while ((q = *p) != NULL) {
                   1453:                        if ((q->isr_intr)(q->isr_arg))
                   1454:                                break;
                   1455:                        p = &q->isr_forw;
                   1456:                }
1.122     is       1457:                single_inst_bclr_b(*draco_intpen, DRIRQ_INT6);
1.104     is       1458:                break;
                   1459: #endif
                   1460:
                   1461:        case 3:
                   1462:        /* VBL */
1.45      chopps   1463:                if (ireq & INTF_BLIT)
1.22      chopps   1464:                        blitter_handler();
1.45      chopps   1465:                if (ireq & INTF_COPER)
1.22      chopps   1466:                        copper_handler();
1.45      chopps   1467:                if (ireq & INTF_VERTB)
1.22      chopps   1468:                        vbl_handler();
                   1469:                break;
1.81      is       1470: #ifdef DRACO
                   1471:        case 5:
                   1472:                p = &isr_supio;
                   1473:                while ((q = *p) != NULL) {
                   1474:                        if ((q->isr_intr)(q->isr_arg))
                   1475:                                break;
                   1476:                        p = &q->isr_forw;
                   1477:                }
                   1478:                break;
                   1479: #endif
1.3       mw       1480: #if 0
                   1481: /* now dealt with in locore.s for speed reasons */
1.22      chopps   1482:        case 5:
                   1483:                /* check RS232 RBF */
                   1484:                serintr (0);
                   1485:
                   1486:                custom.intreq = INTF_DSKSYNC;
                   1487:                break;
                   1488: #endif
                   1489:
                   1490:        case 4:
1.66      is       1491: #ifdef DRACO
                   1492: #include "drsc.h"
                   1493:                if (is_draco())
                   1494: #if NDRSC > 0
                   1495:                        drsc_handler();
                   1496: #else
1.122     is       1497:                        single_inst_bclr_b(*draco_intpen, DRIRQ_SCSI);
1.66      is       1498: #endif
                   1499:                else
                   1500: #endif
1.22      chopps   1501:                audio_handler();
                   1502:                break;
                   1503:        default:
1.80      christos 1504:                printf("intrhand: unexpected sr 0x%x, intreq = 0x%x\n",
1.22      chopps   1505:                    sr, ireq);
                   1506:                break;
                   1507:        }
1.66      is       1508: #ifdef REALLYDEBUG
1.80      christos 1509:        printf("intrhand: leaving.\n");
1.66      is       1510: #endif
1.1       mw       1511: }
                   1512:
                   1513: #if defined(DEBUG) && !defined(PANICBUTTON)
                   1514: #define PANICBUTTON
                   1515: #endif
                   1516:
                   1517: #ifdef PANICBUTTON
                   1518: int panicbutton = 1;   /* non-zero if panic buttons are enabled */
                   1519: int crashandburn = 0;
                   1520: int candbdelay = 50;   /* give em half a second */
1.61      veego    1521: void candbtimer __P((void));
1.141.2.1  bouyer   1522: struct callout candbtimer_ch = CALLOUT_INITIALIZER;
1.1       mw       1523:
1.61      veego    1524: void
1.1       mw       1525: candbtimer()
                   1526: {
                   1527:        crashandburn = 0;
                   1528: }
                   1529: #endif
                   1530:
                   1531: #if 0
                   1532: /*
                   1533:  * Level 7 interrupts can be caused by the keyboard or parity errors.
                   1534:  */
                   1535: nmihand(frame)
                   1536:        struct frame frame;
                   1537: {
                   1538:        if (kbdnmi()) {
                   1539: #ifdef PANICBUTTON
                   1540:                static int innmihand = 0;
                   1541:
                   1542:                /*
                   1543:                 * Attempt to reduce the window of vulnerability for recursive
                   1544:                 * NMIs (e.g. someone holding down the keyboard reset button).
                   1545:                 */
                   1546:                if (innmihand == 0) {
                   1547:                        innmihand = 1;
1.80      christos 1548:                        printf("Got a keyboard NMI\n");
1.1       mw       1549:                        innmihand = 0;
                   1550:                }
                   1551:                if (panicbutton) {
                   1552:                        if (crashandburn) {
                   1553:                                crashandburn = 0;
                   1554:                                panic(panicstr ?
                   1555:                                      "forced crash, nosync" : "forced crash");
                   1556:                        }
                   1557:                        crashandburn++;
1.141.2.1  bouyer   1558:                        callout_reset(&candbtimer_ch, candbdelay,
                   1559:                            candbtimer, NULL);
1.1       mw       1560:                }
                   1561: #endif
                   1562:                return;
                   1563:        }
                   1564:        if (parityerror(&frame))
                   1565:                return;
                   1566:        /* panic?? */
1.80      christos 1567:        printf("unexpected level 7 interrupt ignored\n");
1.1       mw       1568: }
                   1569: #endif
                   1570:
1.31      chopps   1571: /*
                   1572:  * should only get here, if no standard executable. This can currently
                   1573:  * only mean, we're reading an old ZMAGIC file without MID, but since Amiga
                   1574:  * ZMAGIC always worked the `right' way (;-)) just ignore the missing
                   1575:  * MID and proceed to new zmagic code ;-)
                   1576:  */
1.61      veego    1577: int
1.4       mw       1578: cpu_exec_aout_makecmds(p, epp)
1.31      chopps   1579:        struct proc *p;
                   1580:        struct exec_package *epp;
1.1       mw       1581: {
1.31      chopps   1582:        int error = ENOEXEC;
1.71      veego    1583: #ifdef COMPAT_NOMID
1.31      chopps   1584:        struct exec *execp = epp->ep_hdr;
1.71      veego    1585: #endif
1.1       mw       1586:
                   1587: #ifdef COMPAT_NOMID
1.31      chopps   1588:        if (!((execp->a_midmag >> 16) & 0x0fff)
                   1589:            && execp->a_midmag == ZMAGIC)
                   1590:                return(exec_aout_prep_zmagic(p, epp));
1.4       mw       1591: #endif
1.31      chopps   1592:        return(error);
1.4       mw       1593: }

CVSweb <webmaster@jp.NetBSD.org>