[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.96

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

CVSweb <webmaster@jp.NetBSD.org>