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

1.224.2.1! uebayasi    1: /*     $NetBSD$        */
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.185     agc        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"
1.215     apb        85: #include "opt_modular.h"
1.182     martin     86: #include "opt_panicbutton.h"
1.167     aymeric    87:
                     88: #include <sys/cdefs.h>
1.224.2.1! uebayasi   89: __KERNEL_RCSID(0, "$NetBSD$");
1.1       mw         90:
1.9       chopps     91: #include <sys/param.h>
                     92: #include <sys/systm.h>
1.148     thorpej    93: #include <sys/callout.h>
1.9       chopps     94: #include <sys/signalvar.h>
                     95: #include <sys/kernel.h>
                     96: #include <sys/proc.h>
                     97: #include <sys/buf.h>
                     98: #include <sys/reboot.h>
                     99: #include <sys/conf.h>
                    100: #include <sys/file.h>
                    101: #include <sys/malloc.h>
                    102: #include <sys/mbuf.h>
                    103: #include <sys/msgbuf.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.207     ad        111: #include <sys/cpu.h>
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.155     cgd       120: #undef PS      /* XXX netccitt/pk.h conflict with machine/reg.h? */
1.154     mrg       121:
1.143     ragge     122: #define        MAXMEM  64*1024 /* XXX - from cmap.h */
1.121     mhitch    123: #include <uvm/uvm_extern.h>
                    124:
1.103     is        125: #include <sys/sysctl.h>
1.61      veego     126:
                    127: #include <machine/db_machdep.h>
                    128: #include <ddb/db_sym.h>
                    129: #include <ddb/db_extern.h>
                    130:
1.23      chopps    131: #include <machine/reg.h>
                    132: #include <machine/psl.h>
                    133: #include <machine/pte.h>
1.68      mhitch    134: #include <machine/kcore.h>
1.23      chopps    135: #include <dev/cons.h>
                    136: #include <amiga/amiga/isr.h>
1.9       chopps    137: #include <amiga/amiga/custom.h>
1.66      is        138: #ifdef DRACO
                    139: #include <amiga/amiga/drcustom.h>
1.122     is        140: #include <m68k/include/asm_single.h>
1.66      is        141: #endif
1.9       chopps    142: #include <amiga/amiga/cia.h>
                    143: #include <amiga/amiga/cc.h>
                    144: #include <amiga/amiga/memlist.h>
1.45      chopps    145:
1.17      chopps    146: #include "fd.h"
1.22      chopps    147: #include "ser.h"
1.181     ragge     148: #include "ksyms.h"
1.1       mw        149:
1.61      veego     150: /* prototypes */
1.166     aymeric   151: void identifycpu(void);
                    152: vm_offset_t reserve_dumppages(vm_offset_t);
                    153: void dumpsys(void);
                    154: void initcpu(void);
                    155: void straytrap(int, u_short);
                    156: void intrhand(int);
1.64      mhitch    157: #if NSER > 0
1.166     aymeric   158: void ser_outintr(void);
1.64      mhitch    159: #endif
                    160: #if NFD > 0
1.166     aymeric   161: void fdintr(int);
1.64      mhitch    162: #endif
1.165     aymeric   163:
                    164: volatile unsigned int interrupt_depth = 0;
1.61      veego     165:
1.163     chs       166: struct vm_map *phys_map = NULL;
1.121     mhitch    167:
1.202     christos  168: void * msgbufaddr;
1.141     is        169: paddr_t msgbufpa;
1.100     leo       170:
1.171     aymeric   171: int    machineid;
1.1       mw        172: int    maxmem;                 /* max memory per process */
                    173: int    physmem = MAXMEM;       /* max supported memory, changes to actual */
1.220     phx       174:
1.45      chopps    175: /*
1.1       mw        176:  * safepri is a safe priority for sleep to set for a spin-wait
                    177:  * during autoconfiguration or after a panic.
                    178:  */
                    179: int    safepri = PSL_LOWIPL;
                    180: extern  int   freebufspace;
                    181: extern u_int lowram;
                    182:
                    183: /* used in init_main.c */
1.192     jandberg  184: const char *cpu_type = "m68k";
1.23      chopps    185: /* the following is used externally (sysctl_hw) */
1.91      veego     186: char   machine[] = MACHINE;    /* from <machine/param.h> */
1.151     thorpej   187:
                    188: /* Our exported CPU info; we can have only one. */
                    189: struct cpu_info cpu_info_store;
1.166     aymeric   190:
1.102     mhitch    191: /*
                    192:  * current open serial device speed;  used by some SCSI drivers to reduce
                    193:  * DMA transfer lengths.
                    194:  */
                    195: int    ser_open_speed;
1.172     matt      196:
                    197: #ifdef DRACO
                    198: vaddr_t DRCCADDR;
                    199:
                    200: volatile u_int8_t *draco_intena, *draco_intpen, *draco_intfrc;
                    201: volatile u_int8_t *draco_misc;
                    202: volatile struct drioct *draco_ioct;
                    203: #endif
1.102     mhitch    204:
1.5       mw        205:  /*
1.1       mw        206:  * Console initialization: called early on from main,
                    207:  * before vm init or startup.  Do enough configuration
                    208:  * to choose and initialize a console.
                    209:  */
                    210: void
1.218     cegger    211: consinit(void)
1.1       mw        212: {
1.5       mw        213:        /* initialize custom chip interface */
1.66      is        214: #ifdef DRACO
                    215:        if (is_draco()) {
                    216:                /* XXX to be done */
                    217:        } else
                    218: #endif
                    219:                custom_chips_init();
1.1       mw        220:        /*
                    221:         * Initialize the console before we print anything out.
                    222:         */
                    223:        cninit();
1.11      chopps    224:
1.210     ad        225: #if NKSYMS || defined(DDB) || defined(MODULAR)
1.114     tv        226:        {
1.115     mhitch    227:                extern int end[];
1.114     tv        228:                extern int *esym;
                    229:
1.212     martin    230:                ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
1.159     is        231:                    (void *)&end, esym);
1.181     ragge     232:        }
1.159     is        233: #endif
1.181     ragge     234: #ifdef DDB
1.11      chopps    235:         if (boothowto & RB_KDB)
                    236:                 Debugger();
                    237: #endif
1.1       mw        238: }
                    239:
                    240: /*
                    241:  * cpu_startup: allocate memory for variable-sized tables,
1.189     wiz       242:  * initialize CPU, and do autoconfiguration.
1.1       mw        243:  */
                    244: void
1.218     cegger    245: cpu_startup(void)
1.1       mw        246: {
1.136     lukem     247:        char pbuf[9];
1.188     pk        248:        u_int i;
1.1       mw        249: #ifdef DEBUG
                    250:        extern int pmapdebug;
                    251:        int opmapdebug = pmapdebug;
                    252: #endif
1.188     pk        253:        vaddr_t minaddr, maxaddr;
1.1       mw        254:
1.179     thorpej   255:        if (fputype != FPU_NONE)
                    256:                m68k_make_fpu_idle_frame();
                    257:
1.1       mw        258:        /*
                    259:         * Initialize error message buffer (at end of core).
                    260:         */
                    261: #ifdef DEBUG
                    262:        pmapdebug = 0;
                    263: #endif
1.111     is        264:        /*
                    265:         * pmap_bootstrap has positioned this at the end of kernel
                    266:         * memory segment - map and initialize it now.
                    267:         */
                    268:
1.100     leo       269:        for (i = 0; i < btoc(MSGBUFSIZE); i++)
1.180     thorpej   270:                pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE,
                    271:                    msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE,
1.142     thorpej   272:                    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
1.164     chris     273:        pmap_update(pmap_kernel());
1.100     leo       274:        initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
1.1       mw        275:
                    276:        /*
                    277:         * Good {morning,afternoon,evening,night}.
                    278:         */
1.191     lukem     279:        printf("%s%s", copyright, version);
1.1       mw        280:        identifycpu();
1.136     lukem     281:        format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
                    282:        printf("total memory = %s\n", pbuf);
1.5       mw        283:
1.121     mhitch    284:
1.188     pk        285:        minaddr = 0;
1.1       mw        286:
                    287:        /*
                    288:         * Allocate a submap for physio
                    289:         */
1.121     mhitch    290:        phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
1.201     thorpej   291:                                   VM_PHYS_SIZE, 0, false, NULL);
1.1       mw        292:
                    293: #ifdef DEBUG
                    294:        pmapdebug = opmapdebug;
                    295: #endif
1.136     lukem     296:        format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
                    297:        printf("avail memory = %s\n", pbuf);
1.166     aymeric   298:
1.29      chopps    299:        /*
                    300:         * display memory configuration passed from loadbsd
                    301:         */
                    302:        if (memlist->m_nseg > 0 && memlist->m_nseg < 16)
                    303:                for (i = 0; i < memlist->m_nseg; i++)
1.139     is        304:                        printf("memory segment %d at %08x size %08x\n", i,
1.166     aymeric   305:                            memlist->m_seg[i].ms_start,
1.29      chopps    306:                            memlist->m_seg[i].ms_size);
1.66      is        307:
1.78      thorpej   308: #ifdef DEBUG_KERNEL_START
1.80      christos  309:        printf("calling initcpu...\n");
1.66      is        310: #endif
1.1       mw        311:        /*
                    312:         * Set up CPU-specific registers, cache, etc.
                    313:         */
                    314:        initcpu();
                    315:
1.73      is        316: #ifdef DEBUG_KERNEL_START
1.80      christos  317:        printf("survived initcpu...\n");
1.66      is        318: #endif
1.1       mw        319: }
                    320:
                    321: /*
                    322:  * Set registers on exec.
                    323:  */
                    324: void
1.224     matt      325: setregs(struct lwp *l, struct exec_package *pack, vaddr_t stack)
1.1       mw        326: {
1.179     thorpej   327:        struct frame *frame = (struct frame *)l->l_md.md_regs;
1.221     rmind     328:        struct pcb *pcb = lwp_getpcb(l);
1.166     aymeric   329:
1.99      mycroft   330:        frame->f_sr = PSL_USERSET;
1.48      christos  331:        frame->f_pc = pack->ep_entry & ~1;
1.97      mycroft   332:        frame->f_regs[D0] = 0;
                    333:        frame->f_regs[D1] = 0;
                    334:        frame->f_regs[D2] = 0;
                    335:        frame->f_regs[D3] = 0;
                    336:        frame->f_regs[D4] = 0;
                    337:        frame->f_regs[D5] = 0;
                    338:        frame->f_regs[D6] = 0;
                    339:        frame->f_regs[D7] = 0;
                    340:        frame->f_regs[A0] = 0;
                    341:        frame->f_regs[A1] = 0;
1.179     thorpej   342:        frame->f_regs[A2] = (int)l->l_proc->p_psstr;
1.97      mycroft   343:        frame->f_regs[A3] = 0;
                    344:        frame->f_regs[A4] = 0;
                    345:        frame->f_regs[A5] = 0;
                    346:        frame->f_regs[A6] = 0;
1.27      chopps    347:        frame->f_regs[SP] = stack;
                    348:
1.1       mw        349:        /* restore a null state frame */
1.221     rmind     350:        pcb->pcb_fpregs.fpf_null = 0;
1.94      is        351: #ifdef FPU_EMULATE
                    352:        if (!fputype)
1.221     rmind     353:                memset(&pcb->pcb_fpregs, 0, sizeof(struct fpframe));
1.94      is        354:        else
                    355: #endif
1.221     rmind     356:                m68881_restore(&pcb->pcb_fpregs);
1.1       mw        357: }
                    358:
1.23      chopps    359: /*
                    360:  * Info for CTL_HW
                    361:  */
                    362: char cpu_model[120];
1.81      is        363:
                    364: #if defined(M68060)
                    365: int m68060_pcr_init = 0x21;    /* make this patchable */
                    366: #endif
                    367:
1.166     aymeric   368:
1.61      veego     369: void
1.218     cegger    370: identifycpu(void)
1.1       mw        371: {
1.3       mw        372:         /* there's alot of XXX in here... */
1.192     jandberg  373:        const char *mach, *mmu, *fpu;
1.3       mw        374:
1.70      is        375: #ifdef M68060
                    376:        char cpubuf[16];
                    377:        u_int32_t pcr;
                    378: #endif
1.72      is        379:
1.66      is        380: #ifdef DRACO
                    381:        char machbuf[16];
                    382:
                    383:        if (is_draco()) {
1.80      christos  384:                sprintf(machbuf, "DraCo rev.%d", is_draco());
1.66      is        385:                mach = machbuf;
1.166     aymeric   386:        } else
1.66      is        387: #endif
1.23      chopps    388:        if (is_a4000())
                    389:                mach = "Amiga 4000";
                    390:        else if (is_a3000())
                    391:                mach = "Amiga 3000";
1.33      chopps    392:        else if (is_a1200())
                    393:                mach = "Amiga 1200";
1.3       mw        394:        else
1.23      chopps    395:                mach = "Amiga 500/2000";
1.1       mw        396:
1.31      chopps    397:        fpu = NULL;
1.72      is        398: #ifdef M68060
1.66      is        399:        if (machineid & AMIGA_68060) {
1.195     perry     400:                __asm(".word 0x4e7a,0x0808; movl %%d0,%0" : "=d"(pcr) : : "d0");
1.80      christos  401:                sprintf(cpubuf, "68%s060 rev.%d",
1.70      is        402:                    pcr & 0x10000 ? "LC/EC" : "", (pcr>>8)&0xff);
                    403:                cpu_type = cpubuf;
1.66      is        404:                mmu = "/MMU";
1.94      is        405:                if (pcr & 2) {
                    406:                        fpu = "/FPU disabled";
                    407:                        fputype = FPU_NONE;
                    408:                } else if (m68060_pcr_init & 2){
                    409:                        fpu = "/FPU will be disabled";
                    410:                        fputype = FPU_NONE;
                    411:                } else  if (machineid & AMIGA_FPU40) {
                    412:                        fpu = "/FPU";
                    413:                        fputype = FPU_68040; /* XXX */
                    414:                }
1.166     aymeric   415:        } else
1.72      is        416: #endif
                    417:        if (machineid & AMIGA_68040) {
1.5       mw        418:                cpu_type = "m68040";
1.23      chopps    419:                mmu = "/MMU";
1.24      chopps    420:                fpu = "/FPU";
1.81      is        421:                fputype = FPU_68040; /* XXX */
1.24      chopps    422:        } else if (machineid & AMIGA_68030) {
1.23      chopps    423:                cpu_type = "m68030";    /* XXX */
                    424:                mmu = "/MMU";
                    425:        } else {
                    426:                cpu_type = "m68020";
                    427:                mmu = " m68851 MMU";
                    428:        }
1.31      chopps    429:        if (fpu == NULL) {
1.52      chopps    430:                if (machineid & AMIGA_68882) {
1.24      chopps    431:                        fpu = " m68882 FPU";
1.52      chopps    432:                        fputype = FPU_68882;
                    433:                } else if (machineid & AMIGA_68881) {
1.24      chopps    434:                        fpu = " m68881 FPU";
1.52      chopps    435:                        fputype = FPU_68881;
                    436:                } else {
1.24      chopps    437:                        fpu = " no FPU";
1.52      chopps    438:                        fputype = FPU_NONE;
                    439:                }
1.24      chopps    440:        }
1.80      christos  441:        sprintf(cpu_model, "%s (%s CPU%s%s)", mach, cpu_type, mmu, fpu);
                    442:        printf("%s\n", cpu_model);
1.23      chopps    443: }
1.5       mw        444:
1.23      chopps    445: /*
                    446:  * machine dependent system variables.
                    447:  */
1.187     atatat    448: SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
1.23      chopps    449: {
1.1       mw        450:
1.190     atatat    451:        sysctl_createv(clog, 0, NULL, NULL,
                    452:                       CTLFLAG_PERMANENT,
1.187     atatat    453:                       CTLTYPE_NODE, "machdep", NULL,
                    454:                       NULL, 0, NULL, 0,
                    455:                       CTL_MACHDEP, CTL_EOL);
                    456:
1.190     atatat    457:        sysctl_createv(clog, 0, NULL, NULL,
                    458:                       CTLFLAG_PERMANENT,
1.187     atatat    459:                       CTLTYPE_STRUCT, "console_device", NULL,
                    460:                       sysctl_consdev, 0, NULL, sizeof(dev_t),
                    461:                       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
1.1       mw        462: }
1.4       mw        463:
1.3       mw        464: static int waittime = -1;
1.1       mw        465:
1.3       mw        466: void
                    467: bootsync(void)
1.1       mw        468: {
1.21      chopps    469:        if (waittime < 0) {
1.1       mw        470:                waittime = 0;
1.121     mhitch    471:                vfs_shutdown();
1.1       mw        472:                /*
                    473:                 * If we've been adjusting the clock, the todr
                    474:                 * will be out of synch; adjust it now.
                    475:                 */
                    476:                resettodr();
                    477:        }
1.3       mw        478: }
                    479:
1.63      veego     480:
1.27      chopps    481: void
1.216     dsl       482: cpu_reboot(register int howto, char *bootstr)
1.3       mw        483: {
1.221     rmind     484:        struct pcb *pcb = lwp_getpcb(curlwp);
                    485:
1.3       mw        486:        /* take a snap shot before clobbering any registers */
1.221     rmind     487:        if (pcb != NULL)
                    488:                savectx(pcb);
1.3       mw        489:
                    490:        boothowto = howto;
1.61      veego     491:        if ((howto & RB_NOSYNC) == 0)
1.3       mw        492:                bootsync();
1.63      veego     493:
                    494:        /* Disable interrupts. */
                    495:        spl7();
                    496:
                    497:        /* If rebooting and a dump is requested do it. */
                    498:        if (howto & RB_DUMP)
                    499:                dumpsys();
                    500:
1.61      veego     501:        if (howto & RB_HALT) {
1.101     veego     502:                printf("\n");
                    503:                printf("The operating system has halted.\n");
                    504:                printf("Please press any key to reboot.\n\n");
                    505:                cngetc();
1.1       mw        506:        }
1.63      veego     507:
1.101     veego     508:        printf("rebooting...\n");
                    509:        DELAY(1000000);
1.63      veego     510:        doboot();
1.1       mw        511:        /*NOTREACHED*/
                    512: }
1.63      veego     513:
1.1       mw        514:
1.168     tsutsui   515: u_int32_t dumpmag = 0x8fca0101;        /* magic number for savecore */
1.1       mw        516: int    dumpsize = 0;           /* also for savecore */
                    517: long   dumplo = 0;
1.68      mhitch    518: cpu_kcore_hdr_t cpu_kcore_hdr;
1.1       mw        519:
1.193     chs       520: #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
                    521: #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
                    522:
1.61      veego     523: void
1.218     cegger    524: cpu_dumpconf(void)
1.1       mw        525: {
1.89      thorpej   526:        cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
                    527:        struct m68k_kcore_hdr *m = &h->un._m68k;
1.174     gehenna   528:        const struct bdevsw *bdev;
1.1       mw        529:        int nblks;
1.68      mhitch    530:        int i;
1.115     mhitch    531:        extern int end[];
1.89      thorpej   532:
1.219     cegger    533:        memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
1.89      thorpej   534:
                    535:        /*
                    536:         * Intitialize the `dispatcher' portion of the header.
                    537:         */
                    538:        strcpy(h->name, machine);
1.180     thorpej   539:        h->page_size = PAGE_SIZE;
1.89      thorpej   540:        h->kernbase = KERNBASE;
                    541:
                    542:        /*
                    543:         * Fill in information about our MMU configuration.
                    544:         */
                    545:        m->mmutype      = mmutype;
                    546:        m->sg_v         = SG_V;
                    547:        m->sg_frame     = SG_FRAME;
                    548:        m->sg_ishift    = SG_ISHIFT;
                    549:        m->sg_pmask     = SG_PMASK;
                    550:        m->sg40_shift1  = SG4_SHIFT1;
                    551:        m->sg40_mask2   = SG4_MASK2;
                    552:        m->sg40_shift2  = SG4_SHIFT2;
                    553:        m->sg40_mask3   = SG4_MASK3;
                    554:        m->sg40_shift3  = SG4_SHIFT3;
                    555:        m->sg40_addr1   = SG4_ADDR1;
                    556:        m->sg40_addr2   = SG4_ADDR2;
                    557:        m->pg_v         = PG_V;
                    558:        m->pg_frame     = PG_FRAME;
                    559:
                    560:        /*
                    561:         * Initialize the pointer to the kernel segment table.
                    562:         */
1.223     tsutsui   563:        m->sysseg_pa = (paddr_t)pmap_kernel()->pm_stpa;
1.89      thorpej   564:
                    565:        /*
                    566:         * Initialize relocation value such that:
                    567:         *
                    568:         *      pa = (va - KERNBASE) + reloc
                    569:         */
                    570:        m->reloc = lowram;
                    571:
                    572:        /*
                    573:         * Define the end of the relocatable range.
                    574:         */
1.115     mhitch    575:        m->relocend = (u_int32_t)&end;
1.1       mw        576:
1.68      mhitch    577:        /* XXX new corefile format, single segment + chipmem */
1.1       mw        578:        dumpsize = physmem;
1.89      thorpej   579:        m->ram_segs[0].start = lowram;
                    580:        m->ram_segs[0].size  = ctob(physmem);
1.68      mhitch    581:        for (i = 0; i < memlist->m_nseg; i++) {
                    582:                if ((memlist->m_seg[i].ms_attrib & MEMF_CHIP) == 0)
                    583:                        continue;
                    584:                dumpsize += btoc(memlist->m_seg[i].ms_size);
1.89      thorpej   585:                m->ram_segs[1].start = 0;
                    586:                m->ram_segs[1].size  = memlist->m_seg[i].ms_size;
1.68      mhitch    587:                break;
                    588:        }
1.199     yamt      589:        if ((bdev = bdevsw_lookup(dumpdev)) == NULL) {
1.197     mrg       590:                dumpdev = NODEV;
                    591:                return;
                    592:        }
                    593:        if (bdev->d_psize != NULL) {
1.174     gehenna   594:                nblks = (*bdev->d_psize)(dumpdev);
1.1       mw        595:                if (dumpsize > btoc(dbtob(nblks - dumplo)))
                    596:                        dumpsize = btoc(dbtob(nblks - dumplo));
                    597:                else if (dumplo == 0)
1.68      mhitch    598:                        dumplo = nblks - btodb(ctob(dumpsize));
1.1       mw        599:        }
1.68      mhitch    600:        --dumplo;       /* XXX assume header fits in one block */
1.1       mw        601:        /*
1.180     thorpej   602:         * Don't dump on the first PAGE_SIZE (why PAGE_SIZE?)
1.1       mw        603:         * in case the dump device includes a disk label.
                    604:         */
1.180     thorpej   605:        if (dumplo < btodb(PAGE_SIZE))
                    606:                dumplo = btodb(PAGE_SIZE);
1.1       mw        607: }
                    608:
                    609: /*
                    610:  * Doadump comes here after turning off memory management and
                    611:  * getting on the dump stack, either when called above, or by
                    612:  * the auto-restart code.
                    613:  */
1.57      chopps    614: #define BYTES_PER_DUMP MAXPHYS /* Must be a multiple of pagesize XXX small */
1.55      chopps    615: static vm_offset_t dumpspace;
                    616:
                    617: vm_offset_t
1.216     dsl       618: reserve_dumppages(vm_offset_t p)
1.55      chopps    619: {
                    620:        dumpspace = p;
                    621:        return (p + BYTES_PER_DUMP);
                    622: }
                    623:
1.61      veego     624: void
1.218     cegger    625: dumpsys(void)
1.1       mw        626: {
1.68      mhitch    627:        unsigned bytes, i, n, seg;
1.55      chopps    628:        int     maddr, psize;
                    629:        daddr_t blkno;
1.202     christos  630:        int     (*dump)(dev_t, daddr_t, void *, size_t);
1.55      chopps    631:        int     error = 0;
1.68      mhitch    632:        kcore_seg_t *kseg_p;
                    633:        cpu_kcore_hdr_t *chdr_p;
1.193     chs       634:        char    dump_hdr[MDHDRSIZE];
1.174     gehenna   635:        const struct bdevsw *bdev;
1.1       mw        636:
                    637:        if (dumpdev == NODEV)
                    638:                return;
1.174     gehenna   639:        bdev = bdevsw_lookup(dumpdev);
                    640:        if (bdev == NULL || bdev->d_psize == NULL)
                    641:                return;
1.1       mw        642:        /*
                    643:         * For dumps during autoconfiguration,
                    644:         * if dump device has already configured...
                    645:         */
                    646:        if (dumpsize == 0)
1.85      gwr       647:                cpu_dumpconf();
1.108     mycroft   648:        if (dumplo <= 0) {
1.214     he        649:                printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
1.108     mycroft   650:                    minor(dumpdev));
1.1       mw        651:                return;
1.108     mycroft   652:        }
1.214     he        653:        printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
1.108     mycroft   654:            minor(dumpdev), dumplo);
1.55      chopps    655:
1.174     gehenna   656:        psize = (*bdev->d_psize)(dumpdev);
1.80      christos  657:        printf("dump ");
1.55      chopps    658:        if (psize == -1) {
1.80      christos  659:                printf("area unavailable.\n");
1.55      chopps    660:                return;
                    661:        }
1.68      mhitch    662:        kseg_p = (kcore_seg_t *)dump_hdr;
                    663:        chdr_p = (cpu_kcore_hdr_t *)&dump_hdr[ALIGN(sizeof(*kseg_p))];
1.219     cegger    664:        memset(dump_hdr, 0, sizeof(dump_hdr));
1.68      mhitch    665:
                    666:        /*
                    667:         * Generate a segment header
                    668:         */
                    669:        CORE_SETMAGIC(*kseg_p, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
1.193     chs       670:        kseg_p->c_size = MDHDRSIZE - ALIGN(sizeof(*kseg_p));
1.68      mhitch    671:
                    672:        /*
                    673:         * Add the md header
                    674:         */
                    675:
                    676:        *chdr_p = cpu_kcore_hdr;
                    677:
1.55      chopps    678:        bytes = ctob(dumpsize);
1.89      thorpej   679:        maddr = cpu_kcore_hdr.un._m68k.ram_segs[0].start;
1.68      mhitch    680:        seg = 0;
1.55      chopps    681:        blkno = dumplo;
1.174     gehenna   682:        dump = bdev->d_dump;
1.202     christos  683:        error = (*dump) (dumpdev, blkno, (void *)dump_hdr, sizeof(dump_hdr));
1.193     chs       684:        blkno += btodb(sizeof(dump_hdr));
1.68      mhitch    685:        for (i = 0; i < bytes && error == 0; i += n) {
1.55      chopps    686:                /* Print out how many MBs we have to go. */
                    687:                n = bytes - i;
                    688:                if (n && (n % (1024 * 1024)) == 0)
1.211     ad        689:                        printf_nolog("%d ", n / (1024 * 1024));
1.55      chopps    690:
                    691:                /* Limit size for next transfer. */
                    692:                if (n > BYTES_PER_DUMP)
                    693:                        n = BYTES_PER_DUMP;
                    694:
1.68      mhitch    695:                if (maddr == 0) {       /* XXX kvtop chokes on this */
1.180     thorpej   696:                        maddr += PAGE_SIZE;
                    697:                        n -= PAGE_SIZE;
                    698:                        i += PAGE_SIZE;
1.68      mhitch    699:                        ++blkno;        /* XXX skip physical page 0 */
                    700:                }
1.55      chopps    701:                (void) pmap_map(dumpspace, maddr, maddr + n, VM_PROT_READ);
1.202     christos  702:                error = (*dump) (dumpdev, blkno, (void *) dumpspace, n);
1.55      chopps    703:                if (error)
                    704:                        break;
                    705:                maddr += n;
                    706:                blkno += btodb(n);      /* XXX? */
1.89      thorpej   707:                if (maddr >= (cpu_kcore_hdr.un._m68k.ram_segs[seg].start +
                    708:                    cpu_kcore_hdr.un._m68k.ram_segs[seg].size)) {
1.68      mhitch    709:                        ++seg;
1.89      thorpej   710:                        maddr = cpu_kcore_hdr.un._m68k.ram_segs[seg].start;
                    711:                        if (cpu_kcore_hdr.un._m68k.ram_segs[seg].size == 0)
1.68      mhitch    712:                                break;
                    713:                }
1.55      chopps    714:        }
                    715:
                    716:        switch (error) {
1.1       mw        717:
                    718:        case ENXIO:
1.80      christos  719:                printf("device bad\n");
1.1       mw        720:                break;
                    721:
                    722:        case EFAULT:
1.80      christos  723:                printf("device not ready\n");
1.1       mw        724:                break;
                    725:
                    726:        case EINVAL:
1.80      christos  727:                printf("area improper\n");
1.1       mw        728:                break;
                    729:
                    730:        case EIO:
1.80      christos  731:                printf("i/o error\n");
1.1       mw        732:                break;
                    733:
                    734:        default:
1.80      christos  735:                printf("succeeded\n");
1.1       mw        736:                break;
                    737:        }
1.80      christos  738:        printf("\n\n");
1.55      chopps    739:        delay(5000000);         /* 5 seconds */
1.1       mw        740: }
                    741:
1.61      veego     742: void
1.218     cegger    743: initcpu(void)
1.1       mw        744: {
1.166     aymeric   745:        typedef void trapfun(void);
1.93      is        746:
1.67      is        747:        /* XXX should init '40 vecs here, too */
1.94      is        748: #if defined(M68060) || defined(M68040) || defined(DRACO) || defined(FPU_EMULATE)
1.93      is        749:        extern trapfun *vectab[256];
1.70      is        750: #endif
1.66      is        751:
1.90      is        752: #if defined(M68060) || defined(M68040)
1.93      is        753:        extern trapfun addrerr4060;
1.90      is        754: #endif
                    755:
1.72      is        756: #ifdef M68060
1.93      is        757:        extern trapfun buserr60;
1.69      is        758: #if defined(M060SP)
1.82      is        759:        /*extern u_int8_t I_CALL_TOP[];*/
1.93      is        760:        extern trapfun intemu60, fpiemu60, fpdemu60, fpeaemu60;
1.66      is        761:        extern u_int8_t FP_CALL_TOP[];
1.69      is        762: #else
1.93      is        763:        extern trapfun illinst;
1.72      is        764: #endif
1.93      is        765:        extern trapfun fpfault;
1.69      is        766: #endif
1.66      is        767:
1.90      is        768: #ifdef M68040
1.93      is        769:        extern trapfun buserr40;
1.90      is        770: #endif
                    771:
1.70      is        772: #ifdef DRACO
1.93      is        773:        extern trapfun DraCoIntr, DraCoLev1intr, DraCoLev2intr;
1.77      is        774:        u_char dracorev;
1.70      is        775: #endif
                    776:
1.94      is        777: #ifdef FPU_EMULATE
                    778:        extern trapfun fpemuli;
                    779: #endif
                    780:
1.70      is        781: #ifdef M68060
1.66      is        782:        if (machineid & AMIGA_68060) {
1.94      is        783:                if (machineid & AMIGA_FPU40 && m68060_pcr_init & 2) {
1.166     aymeric   784:                        /*
1.94      is        785:                         * in this case, we're about to switch the FPU off;
                    786:                         * do a FNOP to avoid stray FP traps later
                    787:                         */
                    788:                        __asm("fnop");
                    789:                        /* ... and mark FPU as absent for identifyfpu() */
                    790:                        machineid &= ~(AMIGA_FPU40|AMIGA_68882|AMIGA_68881);
                    791:                }
1.195     perry     792:                __asm volatile ("movl %0,%%d0; .word 0x4e7b,0x0808" : :
1.66      is        793:                        "d"(m68060_pcr_init):"d0" );
1.90      is        794:
                    795:                /* bus/addrerr vectors */
1.93      is        796:                vectab[2] = buserr60;
                    797:                vectab[3] = addrerr4060;
1.66      is        798: #if defined(M060SP)
                    799:
                    800:                /* integer support */
1.93      is        801:                vectab[61] = intemu60/*(trapfun *)&I_CALL_TOP[128 + 0x00]*/;
1.66      is        802:
                    803:                /* floating point support */
1.81      is        804:                /*
                    805:                 * XXX maybe we really should run-time check for the
                    806:                 * stack frame format here:
                    807:                 */
1.93      is        808:                vectab[11] = fpiemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x30]*/;
1.81      is        809:
1.93      is        810:                vectab[55] = fpdemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x38]*/;
                    811:                vectab[60] = fpeaemu60/*(trapfun *)&FP_CALL_TOP[128 + 0x40]*/;
1.66      is        812:
1.93      is        813:                vectab[54] = (trapfun *)&FP_CALL_TOP[128 + 0x00];
                    814:                vectab[52] = (trapfun *)&FP_CALL_TOP[128 + 0x08];
                    815:                vectab[53] = (trapfun *)&FP_CALL_TOP[128 + 0x10];
                    816:                vectab[51] = (trapfun *)&FP_CALL_TOP[128 + 0x18];
                    817:                vectab[50] = (trapfun *)&FP_CALL_TOP[128 + 0x20];
                    818:                vectab[49] = (trapfun *)&FP_CALL_TOP[128 + 0x28];
1.66      is        819:
                    820: #else
1.93      is        821:                vectab[61] = illinst;
1.66      is        822: #endif
1.93      is        823:                vectab[48] = fpfault;
1.66      is        824:        }
                    825: #endif
1.70      is        826:
1.81      is        827: /*
1.166     aymeric   828:  * Vector initialization for special motherboards
1.81      is        829:  */
1.90      is        830: #ifdef M68040
                    831: #ifdef M68060
                    832:        else
                    833: #endif
                    834:        if (machineid & AMIGA_68040) {
                    835:                /* addrerr vector */
1.93      is        836:                vectab[2] = buserr40;
                    837:                vectab[3] = addrerr4060;
1.90      is        838:        }
                    839: #endif
1.94      is        840:
                    841: #ifdef FPU_EMULATE
                    842:        if (!(machineid & (AMIGA_68881|AMIGA_68882|AMIGA_FPU40))) {
                    843:                vectab[11] = fpemuli;
                    844:                printf("FPU software emulation initialized.\n");
                    845:        }
                    846: #endif
                    847:
                    848: /*
1.166     aymeric   849:  * Vector initialization for special motherboards
1.94      is        850:  */
1.81      is        851:
1.70      is        852: #ifdef DRACO
1.77      is        853:        dracorev = is_draco();
                    854:        if (dracorev) {
                    855:                if (dracorev >= 4) {
1.93      is        856:                        vectab[24+1] = DraCoLev1intr;
                    857:                        vectab[24+2] = DraCoIntr;
1.77      is        858:                } else {
1.93      is        859:                        vectab[24+1] = DraCoIntr;
                    860:                        vectab[24+2] = DraCoLev2intr;
1.77      is        861:                }
1.93      is        862:                vectab[24+3] = DraCoIntr;
                    863:                vectab[24+4] = DraCoIntr;
                    864:                vectab[24+5] = DraCoIntr;
                    865:                vectab[24+6] = DraCoIntr;
1.70      is        866:        }
                    867: #endif
1.1       mw        868: }
                    869:
1.61      veego     870: void
1.216     dsl       871: straytrap(int pc, u_short evec)
1.1       mw        872: {
1.80      christos  873:        printf("unexpected trap format %x (vector offset %x) from %x\n",
1.66      is        874:               evec>>12, evec & 0xFFF, pc);
1.42      chopps    875: /*XXX*/        panic("straytrap");
1.1       mw        876: }
                    877:
                    878: int    *nofault;
                    879:
1.61      veego     880: int
1.216     dsl       881: badaddr(register void *addr)
1.1       mw        882: {
                    883:        register int i;
                    884:        label_t faultbuf;
                    885:
                    886: #ifdef lint
                    887:        i = *addr; if (i) return(0);
                    888: #endif
                    889:        nofault = (int *) &faultbuf;
                    890:        if (setjmp((label_t *)nofault)) {
                    891:                nofault = (int *) 0;
                    892:                return(1);
                    893:        }
                    894:        i = *(volatile short *)addr;
                    895:        nofault = (int *) 0;
                    896:        return(0);
                    897: }
                    898:
1.61      veego     899: int
1.216     dsl       900: badbaddr(register void *addr)
1.1       mw        901: {
                    902:        register int i;
                    903:        label_t faultbuf;
                    904:
                    905: #ifdef lint
                    906:        i = *addr; if (i) return(0);
                    907: #endif
                    908:        nofault = (int *) &faultbuf;
                    909:        if (setjmp((label_t *)nofault)) {
                    910:                nofault = (int *) 0;
                    911:                return(1);
                    912:        }
                    913:        i = *(volatile char *)addr;
                    914:        nofault = (int *) 0;
                    915:        return(0);
                    916: }
                    917:
1.45      chopps    918: struct isr *isr_ports;
1.66      is        919: #ifdef DRACO
                    920: struct isr *isr_slot3;
1.81      is        921: struct isr *isr_supio;
1.66      is        922: #endif
1.45      chopps    923: struct isr *isr_exter;
                    924:
                    925: void
1.216     dsl       926: add_isr(struct isr *isr)
1.45      chopps    927: {
                    928:        struct isr **p, *q;
                    929:
1.66      is        930: #ifdef DRACO
                    931:        switch (isr->isr_ipl) {
                    932:        case 2:
                    933:                p = &isr_ports;
                    934:                break;
                    935:        case 3:
                    936:                p = &isr_slot3;
                    937:                break;
1.81      is        938:        case 5:
                    939:                p = &isr_supio;
                    940:                break;
1.70      is        941:        default:        /* was case 6:; make gcc -Wall quiet */
1.66      is        942:                p = &isr_exter;
                    943:                break;
                    944:        }
                    945: #else
1.45      chopps    946:        p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter;
1.66      is        947: #endif
1.45      chopps    948:        while ((q = *p) != NULL)
                    949:                p = &q->isr_forw;
                    950:        isr->isr_forw = NULL;
                    951:        *p = isr;
                    952:        /* enable interrupt */
1.66      is        953: #ifdef DRACO
                    954:        if (is_draco())
1.81      is        955:                switch(isr->isr_ipl) {
                    956:                        case 6:
1.122     is        957:                                single_inst_bset_b(*draco_intena, DRIRQ_INT6);
1.81      is        958:                                break;
                    959:                        case 2:
1.122     is        960:                                single_inst_bset_b(*draco_intena, DRIRQ_INT2);
1.81      is        961:                                break;
                    962:                        default:
                    963:                                break;
                    964:                }
1.166     aymeric   965:        else
1.66      is        966: #endif
1.166     aymeric   967:                custom.intena = isr->isr_ipl == 2 ?
1.66      is        968:                    INTF_SETCLR | INTF_PORTS :
                    969:                    INTF_SETCLR | INTF_EXTER;
1.45      chopps    970: }
                    971:
                    972: void
1.216     dsl       973: remove_isr(struct isr *isr)
1.45      chopps    974: {
                    975:        struct isr **p, *q;
                    976:
1.66      is        977: #ifdef DRACO
                    978:        switch (isr->isr_ipl) {
                    979:        case 2:
                    980:                p = &isr_ports;
                    981:                break;
                    982:        case 3:
                    983:                p = &isr_slot3;
                    984:                break;
1.81      is        985:        case 5:
                    986:                p = &isr_supio;
                    987:                break;
1.70      is        988:        default:        /* XXX to make gcc -Wall quiet, was 6: */
1.66      is        989:                p = &isr_exter;
                    990:                break;
                    991:        }
                    992: #else
1.45      chopps    993:        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66      is        994: #endif
                    995:
1.45      chopps    996:        while ((q = *p) != NULL && q != isr)
                    997:                p = &q->isr_forw;
                    998:        if (q)
                    999:                *p = q->isr_forw;
                   1000:        else
                   1001:                panic("remove_isr: handler not registered");
                   1002:        /* disable interrupt if no more handlers */
1.66      is       1003: #ifdef DRACO
                   1004:        switch (isr->isr_ipl) {
                   1005:        case 2:
                   1006:                p = &isr_ports;
                   1007:                break;
                   1008:        case 3:
                   1009:                p = &isr_slot3;
                   1010:                break;
1.81      is       1011:        case 5:
                   1012:                p = &isr_supio;
                   1013:                break;
1.66      is       1014:        case 6:
                   1015:                p = &isr_exter;
                   1016:                break;
                   1017:        }
                   1018: #else
1.45      chopps   1019:        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
1.66      is       1020: #endif
1.128     is       1021:        if (*p == NULL) {
1.66      is       1022: #ifdef DRACO
1.81      is       1023:                if (is_draco()) {
                   1024:                        switch(isr->isr_ipl) {
                   1025:                                case 2:
1.122     is       1026:                                        single_inst_bclr_b(*draco_intena,
                   1027:                                            DRIRQ_INT2);
1.81      is       1028:                                        break;
                   1029:                                case 6:
1.122     is       1030:                                        single_inst_bclr_b(*draco_intena,
                   1031:                                            DRIRQ_INT6);
1.81      is       1032:                                        break;
                   1033:                                default:
                   1034:                                        break;
                   1035:                        }
                   1036:                } else
1.66      is       1037: #endif
1.166     aymeric  1038:                        custom.intena = isr->isr_ipl == 6 ?
1.66      is       1039:                            INTF_EXTER : INTF_PORTS;
1.128     is       1040:        }
1.45      chopps   1041: }
                   1042:
1.207     ad       1043: static int idepth;
                   1044:
1.61      veego    1045: void
1.216     dsl      1046: intrhand(int sr)
1.1       mw       1047: {
1.22      chopps   1048:        register unsigned int ipl;
                   1049:        register unsigned short ireq;
1.45      chopps   1050:        register struct isr **p, *q;
1.1       mw       1051:
1.207     ad       1052:        idepth++;
1.22      chopps   1053:        ipl = (sr >> 8) & 7;
1.66      is       1054: #ifdef REALLYDEBUG
1.80      christos 1055:        printf("intrhand: got int. %d\n", ipl);
1.66      is       1056: #endif
                   1057: #ifdef DRACO
                   1058:        if (is_draco())
                   1059:                ireq = ((ipl == 1)  && (*draco_intfrc & DRIRQ_SOFT) ?
                   1060:                    INTF_SOFTINT : 0);
                   1061:        else
                   1062: #endif
                   1063:                ireq = custom.intreqr;
1.1       mw       1064:
1.22      chopps   1065:        switch (ipl) {
                   1066:        case 1:
1.66      is       1067: #ifdef DRACO
                   1068:                if (is_draco() && (draco_ioct->io_status & DRSTAT_KBDRECV))
                   1069:                        drkbdintr();
                   1070: #endif
1.22      chopps   1071:                if (ireq & INTF_TBE) {
                   1072: #if NSER > 0
                   1073:                        ser_outintr();
                   1074: #else
                   1075:                        custom.intreq = INTF_TBE;
                   1076: #endif
                   1077:                }
                   1078:
                   1079:                if (ireq & INTF_DSKBLK) {
1.17      chopps   1080: #if NFD > 0
1.22      chopps   1081:                        fdintr(0);
1.17      chopps   1082: #endif
1.22      chopps   1083:                        custom.intreq = INTF_DSKBLK;
                   1084:                }
                   1085:                if (ireq & INTF_SOFTINT) {
1.220     phx      1086:                        /* sicallback handling removed */
                   1087: #ifdef DEBUG
                   1088:                        printf("intrhand: SOFTINT ignored\n");
1.66      is       1089: #endif
1.220     phx      1090:                        custom.intreq = INTF_SOFTINT;
1.22      chopps   1091:                }
                   1092:                break;
                   1093:
                   1094:        case 2:
1.45      chopps   1095:                p = &isr_ports;
                   1096:                while ((q = *p) != NULL) {
                   1097:                        if ((q->isr_intr)(q->isr_arg))
                   1098:                                break;
                   1099:                        p = &q->isr_forw;
                   1100:                }
                   1101:                if (q == NULL)
                   1102:                        ciaa_intr ();
1.66      is       1103: #ifdef DRACO
                   1104:                if (is_draco())
1.122     is       1105:                        single_inst_bclr_b(*draco_intpen, DRIRQ_INT2);
1.66      is       1106:                else
                   1107: #endif
                   1108:                        custom.intreq = INTF_PORTS;
1.104     is       1109:
1.22      chopps   1110:                break;
1.104     is       1111:
                   1112: #ifdef DRACO
                   1113:        /* only handled here for DraCo */
                   1114:        case 6:
                   1115:                p = &isr_exter;
                   1116:                while ((q = *p) != NULL) {
                   1117:                        if ((q->isr_intr)(q->isr_arg))
                   1118:                                break;
                   1119:                        p = &q->isr_forw;
                   1120:                }
1.122     is       1121:                single_inst_bclr_b(*draco_intpen, DRIRQ_INT6);
1.104     is       1122:                break;
                   1123: #endif
                   1124:
1.166     aymeric  1125:        case 3:
1.104     is       1126:        /* VBL */
1.166     aymeric  1127:                if (ireq & INTF_BLIT)
1.22      chopps   1128:                        blitter_handler();
1.166     aymeric  1129:                if (ireq & INTF_COPER)
1.22      chopps   1130:                        copper_handler();
1.166     aymeric  1131:                if (ireq & INTF_VERTB)
1.22      chopps   1132:                        vbl_handler();
                   1133:                break;
1.81      is       1134: #ifdef DRACO
                   1135:        case 5:
                   1136:                p = &isr_supio;
                   1137:                while ((q = *p) != NULL) {
                   1138:                        if ((q->isr_intr)(q->isr_arg))
                   1139:                                break;
                   1140:                        p = &q->isr_forw;
                   1141:                }
                   1142:                break;
                   1143: #endif
1.3       mw       1144: #if 0
                   1145: /* now dealt with in locore.s for speed reasons */
1.22      chopps   1146:        case 5:
                   1147:                /* check RS232 RBF */
                   1148:                serintr (0);
                   1149:
                   1150:                custom.intreq = INTF_DSKSYNC;
                   1151:                break;
                   1152: #endif
                   1153:
                   1154:        case 4:
1.66      is       1155: #ifdef DRACO
                   1156: #include "drsc.h"
                   1157:                if (is_draco())
                   1158: #if NDRSC > 0
                   1159:                        drsc_handler();
                   1160: #else
1.122     is       1161:                        single_inst_bclr_b(*draco_intpen, DRIRQ_SCSI);
1.66      is       1162: #endif
                   1163:                else
                   1164: #endif
1.22      chopps   1165:                audio_handler();
                   1166:                break;
                   1167:        default:
1.80      christos 1168:                printf("intrhand: unexpected sr 0x%x, intreq = 0x%x\n",
1.22      chopps   1169:                    sr, ireq);
                   1170:                break;
                   1171:        }
1.66      is       1172: #ifdef REALLYDEBUG
1.80      christos 1173:        printf("intrhand: leaving.\n");
1.66      is       1174: #endif
1.207     ad       1175:        idepth--;
                   1176: }
                   1177:
                   1178: bool
                   1179: cpu_intr_p(void)
                   1180: {
                   1181:
                   1182:        return idepth != 0;
1.1       mw       1183: }
                   1184:
                   1185: #if defined(DEBUG) && !defined(PANICBUTTON)
                   1186: #define PANICBUTTON
                   1187: #endif
                   1188:
                   1189: #ifdef PANICBUTTON
                   1190: int panicbutton = 1;   /* non-zero if panic buttons are enabled */
                   1191: int crashandburn = 0;
                   1192: int candbdelay = 50;   /* give em half a second */
1.166     aymeric  1193: void candbtimer(void);
1.204     ad       1194: callout_t candbtimer_ch;
1.1       mw       1195:
1.61      veego    1196: void
1.218     cegger   1197: candbtimer(void)
1.1       mw       1198: {
                   1199:        crashandburn = 0;
                   1200: }
                   1201: #endif
                   1202:
                   1203: #if 0
                   1204: /*
                   1205:  * Level 7 interrupts can be caused by the keyboard or parity errors.
                   1206:  */
1.216     dsl      1207: nmihand(struct frame frame)
1.1       mw       1208: {
                   1209:        if (kbdnmi()) {
                   1210: #ifdef PANICBUTTON
                   1211:                static int innmihand = 0;
                   1212:
                   1213:                /*
                   1214:                 * Attempt to reduce the window of vulnerability for recursive
                   1215:                 * NMIs (e.g. someone holding down the keyboard reset button).
                   1216:                 */
                   1217:                if (innmihand == 0) {
                   1218:                        innmihand = 1;
1.80      christos 1219:                        printf("Got a keyboard NMI\n");
1.1       mw       1220:                        innmihand = 0;
                   1221:                }
                   1222:                if (panicbutton) {
                   1223:                        if (crashandburn) {
                   1224:                                crashandburn = 0;
                   1225:                                panic(panicstr ?
                   1226:                                      "forced crash, nosync" : "forced crash");
                   1227:                        }
                   1228:                        crashandburn++;
1.148     thorpej  1229:                        callout_reset(&candbtimer_ch, candbdelay,
                   1230:                            candbtimer, NULL);
1.1       mw       1231:                }
                   1232: #endif
                   1233:                return;
                   1234:        }
                   1235:        if (parityerror(&frame))
                   1236:                return;
                   1237:        /* panic?? */
1.80      christos 1238:        printf("unexpected level 7 interrupt ignored\n");
1.1       mw       1239: }
                   1240: #endif
                   1241:
1.31      chopps   1242: /*
                   1243:  * should only get here, if no standard executable. This can currently
                   1244:  * only mean, we're reading an old ZMAGIC file without MID, but since Amiga
                   1245:  * ZMAGIC always worked the `right' way (;-)) just ignore the missing
                   1246:  * MID and proceed to new zmagic code ;-)
                   1247:  */
1.61      veego    1248: int
1.216     dsl      1249: cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
1.1       mw       1250: {
1.31      chopps   1251:        int error = ENOEXEC;
1.71      veego    1252: #ifdef COMPAT_NOMID
1.31      chopps   1253:        struct exec *execp = epp->ep_hdr;
1.71      veego    1254: #endif
1.1       mw       1255:
                   1256: #ifdef COMPAT_NOMID
1.31      chopps   1257:        if (!((execp->a_midmag >> 16) & 0x0fff)
                   1258:            && execp->a_midmag == ZMAGIC)
1.194     christos 1259:                return(exec_aout_prep_zmagic(l, epp));
1.4       mw       1260: #endif
1.31      chopps   1261:        return(error);
1.4       mw       1262: }
1.162     is       1263:
1.210     ad       1264: #ifdef MODULAR
1.162     is       1265:
                   1266: int _spllkm6(void);
                   1267: int _spllkm7(void);
                   1268:
                   1269: #ifdef LEV6_DEFER
                   1270: int _spllkm6() {
                   1271:        return spl4();
                   1272: };
                   1273:
                   1274: int _spllkm7() {
                   1275:        return spl4();
                   1276: };
                   1277:
                   1278: #else
                   1279:
                   1280: int _spllkm6() {
                   1281:        return spl6();
                   1282: };
                   1283:
                   1284: int _spllkm7() {
                   1285:        return spl7();
1.166     aymeric  1286: };
1.162     is       1287:
                   1288: #endif
                   1289:
                   1290: #endif
1.200     yamt     1291:
                   1292: int ipl2spl_table[_NIPL] = {
                   1293:        [IPL_NONE] = PSL_IPL0|PSL_S,
                   1294:        [IPL_SOFTCLOCK] = PSL_IPL1|PSL_S,
                   1295:        [IPL_VM] = PSL_IPL4|PSL_S,
                   1296: #if defined(LEV6_DEFER)
1.222     mhitch   1297:        [IPL_SCHED] = PSL_IPL4|PSL_S,
1.200     yamt     1298:        [IPL_HIGH] = PSL_IPL4|PSL_S,
                   1299: #else /* defined(LEV6_DEFER) */
1.222     mhitch   1300:        [IPL_SCHED] = PSL_IPL6|PSL_S,
1.200     yamt     1301:        [IPL_HIGH] = PSL_IPL7|PSL_S,
                   1302: #endif /* defined(LEV6_DEFER) */
                   1303: };

CVSweb <webmaster@jp.NetBSD.org>