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

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

CVSweb <webmaster@jp.NetBSD.org>