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

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

CVSweb <webmaster@jp.NetBSD.org>