diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mvme88k/mvme88k/machdep.c | 293 |
1 files changed, 224 insertions, 69 deletions
diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c index f7f4878538e..b527da47e5f 100644 --- a/sys/arch/mvme88k/mvme88k/machdep.c +++ b/sys/arch/mvme88k/mvme88k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.77 2001/12/20 06:07:28 smurph Exp $ */ +/* $OpenBSD: machdep.c,v 1.78 2001/12/20 06:43:23 smurph Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -139,6 +139,9 @@ void identifycpu __P((void)); void save_u_area __P((struct proc *, vm_offset_t)); void load_u_area __P((struct proc *)); void dumpconf __P((void)); +void m187_ext_int __P((u_int v, struct m88100_saved_state *eframe)); +void m188_ext_int __P((u_int v, struct m88100_saved_state *eframe)); +void m197_ext_int __P((u_int v, struct m88100_saved_state *eframe)); volatile unsigned char *ivec[] = { (unsigned char *)0xFFFE0003, /* not used, no such thing as int 0 */ @@ -757,9 +760,6 @@ allocsys(v) * Set registers on exec. * Clear all except sp and pc. */ - -/* MVME197 TODO list :-) smurph */ - void setregs(p, pack, stack, retval) struct proc *p; @@ -797,19 +797,35 @@ setregs(p, pack, stack, retval) } #endif /* 0 */ bzero((caddr_t)tf, sizeof *tf); - tf->epsr = PSR_USER; /* user mode, interrupts enabled, fp enabled */ -/* tf->epsr = PSR_USER | PSR_MXM;*/ /* user mode, interrupts enabled, fp enabled, MXM Mask */ + + if (cputyp == CPU_88110) { + /* + * user mode, serialize mem, interrupts enabled, + * graphics unit, fp enabled + */ + tf->epsr = PSR_SRM | PSR_SFD; + } else { + /* + * user mode, interrupts enabled, + * no graphics unit, fp enabled + */ + tf->epsr = PSR_SFD | PSR_SFD2; + } /* * We want to start executing at pack->ep_entry. The way to * do this is force the processor to fetch from ep_entry. Set * NIP to something bogus and invalid so that it will be a NOOP. * And set sfip to ep_entry with valid bit on so that it will be - * fetched. + * fetched. mc88110 - just set exip to pack->ep_entry. */ - + if (cputyp == CPU_88110) { + tf->exip = pack->ep_entry & ~3; + printf("exec @ 0x%x\n", tf->exip); + } else { tf->snip = pack->ep_entry & ~3; tf->sfip = (pack->ep_entry & ~3) | FIP_V; + } tf->r[2] = stack; tf->r[31] = stack; retval[1] = 0; @@ -844,7 +860,6 @@ int sigpid = 0; /* * Send an interrupt to process. */ -/* MVME197 TODO list :-) smurph */ void sendsig(catcher, sig, mask, code, type, val) sig_t catcher; @@ -887,7 +902,7 @@ sendsig(catcher, sig, mask, code, type, val) #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) || - (sigdebug & SDB_KSTACK) && p->p_pid == sigpid) + ((sigdebug & SDB_KSTACK) && (p->p_pid == sigpid))) printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n", p->p_pid, sig, &oonstack, fp, &fp->sf_sc); #endif @@ -911,13 +926,23 @@ sendsig(catcher, sig, mask, code, type, val) */ bcopy((caddr_t)tf->r, (caddr_t)sf.sf_sc.sc_regs, sizeof(sf.sf_sc.sc_regs)); + if (cputyp != CPU_88110) { + /* mc88100 */ sf.sf_sc.sc_xip = tf->sxip & ~3; sf.sf_sc.sc_nip = tf->snip & ~3; sf.sf_sc.sc_fip = tf->sfip & ~3; + } else { + /* mc88110 */ + sf.sf_sc.sc_xip = tf->exip & ~3; + sf.sf_sc.sc_nip = tf->enip & ~3; + sf.sf_sc.sc_fip = 0; + } sf.sf_sc.sc_ps = tf->epsr; sf.sf_sc.sc_sp = tf->r[31]; sf.sf_sc.sc_fpsr = tf->fpsr; sf.sf_sc.sc_fpcr = tf->fpcr; + if (cputyp != CPU_88110) { + /* mc88100 */ sf.sf_sc.sc_ssbr = tf->ssbr; sf.sf_sc.sc_dmt0 = tf->dmt0; sf.sf_sc.sc_dmd0 = tf->dmd0; @@ -928,6 +953,19 @@ sendsig(catcher, sig, mask, code, type, val) sf.sf_sc.sc_dmt2 = tf->dmt2; sf.sf_sc.sc_dmd2 = tf->dmd2; sf.sf_sc.sc_dma2 = tf->dma2; + } else { + /* mc88110 */ + sf.sf_sc.sc_dsr = tf->dsr; + sf.sf_sc.sc_dlar = tf->dlar; + sf.sf_sc.sc_dpar = tf->dpar; + sf.sf_sc.sc_isr = tf->isr; + sf.sf_sc.sc_ilar = tf->ilar; + sf.sf_sc.sc_ipar = tf->ipar; + sf.sf_sc.sc_isap = tf->isap; + sf.sf_sc.sc_dsap = tf->dsap; + sf.sf_sc.sc_iuap = tf->iuap; + sf.sf_sc.sc_duap = tf->duap; + } sf.sf_sc.sc_fpecr = tf->fpecr; sf.sf_sc.sc_fphs1 = tf->fphs1; sf.sf_sc.sc_fpls1 = tf->fpls1; @@ -955,12 +993,19 @@ sendsig(catcher, sig, mask, code, type, val) * Signal trampoline code is at base of user stack. */ addr = (int)PS_STRINGS - szsigcode; + if (cputyp != CPU_88110) { + /* mc88100 */ tf->snip = (addr & ~3) | NIP_V; tf->sfip = (tf->snip + 4) | FIP_V; + } else { + /* mc88110 */ + tf->exip = (addr & ~3); + tf->enip = (tf->exip + 4); + } tf->r[31] = (unsigned)fp; #ifdef DEBUG if ((sigdebug & SDB_FOLLOW) || - (sigdebug & SDB_KSTACK) && p->p_pid == sigpid) + ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)) printf("sendsig(%d): sig %d returns\n", p->p_pid, sig); #endif } @@ -975,10 +1020,8 @@ sendsig(catcher, sig, mask, code, type, val) * psl to gain improper priviledges or to cause * a machine fault. */ -/* ARGSUSED */ - -/* MVME197 TODO list :-) smurph */ +/* ARGSUSED */ int sys_sigreturn(p, v, retval) struct proc *p; @@ -1023,15 +1066,24 @@ register_t *retval; * bcopy(sc_reg to tf, sizeof sigcontext - 2 words) * XXX nivas */ - bcopy((caddr_t)scp->sc_regs, (caddr_t)tf->r, sizeof(scp->sc_regs)); + if (cputyp != CPU_88110) { + /* mc88100 */ tf->sxip = (scp->sc_xip) | XIP_V; tf->snip = (scp->sc_nip) | NIP_V; tf->sfip = (scp->sc_fip) | FIP_V; + } else { + /* mc88110 */ + tf->exip = (scp->sc_xip); + tf->enip = (scp->sc_nip); + tf->sfip = 0; + } tf->epsr = scp->sc_ps; tf->r[31] = scp->sc_sp; tf->fpsr = scp->sc_fpsr; tf->fpcr = scp->sc_fpcr; + if (cputyp != CPU_88110) { + /* mc88100 */ tf->ssbr = scp->sc_ssbr; tf->dmt0 = scp->sc_dmt0; tf->dmd0 = scp->sc_dmd0; @@ -1042,6 +1094,19 @@ register_t *retval; tf->dmt2 = scp->sc_dmt2; tf->dmd2 = scp->sc_dmd2; tf->dma2 = scp->sc_dma2; + } else { + /* mc88110 */ + tf->dsr = scp->sc_dsr; + tf->dlar = scp->sc_dlar; + tf->dpar = scp->sc_dpar; + tf->isr = scp->sc_isr; + tf->ilar = scp->sc_ilar; + tf->ipar = scp->sc_ipar; + tf->isap = scp->sc_isap; + tf->dsap = scp->sc_dsap; + tf->iuap = scp->sc_iuap; + tf->duap = scp->sc_duap; + } tf->fpecr = scp->sc_fpecr; tf->fphs1 = scp->sc_fphs1; tf->fpls1 = scp->sc_fpls1; @@ -1685,9 +1750,9 @@ out_m188: * the routine. */ -#if defined(MVME187) || defined(MVME197) +#ifdef MVME187 void -sbc_ext_int(u_int v, struct m88100_saved_state *eframe) +m187_ext_int(u_int v, struct m88100_saved_state *eframe) { register u_char mask, level; register struct intrhand *intr; @@ -1786,15 +1851,117 @@ sbc_ext_int(u_int v, struct m88100_saved_state *eframe) disable_interrupt(); out: -#ifdef MVME187 - if (brdtyp != BRD_197) { if (eframe->dmt0 & DMT_VALID) { - trap18x(T_DATAFLT, eframe); + trap18x(T_DATAFLT, eframe); data_access_emulation((unsigned *)eframe); eframe->dmt0 &= ~DMT_VALID; } + mask = eframe->mask; + + /* + * Restore the mask level to what it was when the interrupt + * was taken. + */ + setipl((u_char)mask); +} +#endif /* MVME187 */ + +#ifdef MVME197 +void +m197_ext_int(u_int v, struct m88100_saved_state *eframe) +{ + register u_char mask, level, src; + register struct intrhand *intr; + int ret; + u_char vec; + + /* get src and mask */ + asm volatile("ld.b %0,%1" : "=r" (mask) : "" (*md.intr_mask)); + asm volatile("ld.b %0,%1" : "=r" (src) : "" (*md.intr_src)); + + if (v == T_NON_MASK) { + /* This is the abort switch */ + level = IPL_NMI; + vec = BS_ABORTVEC; + } else { + /* get level */ + asm volatile("ld.b %0,%1" : "=r" (level) : "" (*md.intr_ipl)); } -#endif + + /* + * Interrupting level cannot be 0--0 doesn't produce an interrupt. + * Weird! XXX nivas + */ + + if (level == 0) { + printf("Bogons... level %x and mask %x\n", level, mask); + goto m197beatit; + } + + /* and block interrupts at level or lower */ + setipl((u_char)level); + /* and stash it away in the trap frame */ + eframe->mask = mask; + + if (level > 7 || (char)level < 0) { + panic("int level (%x) is not between 0 and 7", level); + } + + if (v != T_NON_MASK) { + /* generate IACK and get the vector */ + asm volatile("tb1 0, r0, 0"); + if (guarded_access(ivec[level], 1, &vec) == EFAULT) { + printf("Unable to get vector for this interrupt (level %x)\n", level); + goto m197out; + } + asm volatile("tb1 0, r0, 0"); + asm volatile("tb1 0, r0, 0"); + asm volatile("tb1 0, r0, 0"); + } + + if (vec > 0xFF) { + panic("interrupt vector %x greater than 255", vec); + } + + enable_interrupt(); + + if ((intr = intr_handlers[vec]) == 0) { + /* increment intr counter */ + intrcnt[M88K_SPUR_IRQ]++; + printf("Spurious interrupt (level %x and vec %x)\n", + level, vec); + } + if (intr && intr->ih_ipl != level) { + panic("Handler ipl %x not the same as level %x. vec = 0x%x", + intr->ih_ipl, level, vec); + } + + /* + * Walk through all interrupt handlers in the chain for the + * given vector, calling each handler in turn, till some handler + * returns a value != 0. + */ + + for (ret = 0; intr; intr = intr->ih_next) { + if (intr->ih_wantframe != 0) + ret = (*intr->ih_fn)((void *)eframe); + else + ret = (*intr->ih_fn)(intr->ih_arg); + if (ret){ + /* increment intr counter */ + intrcnt[level]++; + break; + } + } + + if (ret == 0) { + printf("Unclaimed interrupt (level %x and vec %x)\n", + level, vec); + } + + disable_interrupt(); + +m197out: mask = eframe->mask; /* @@ -1802,8 +1969,11 @@ out: * was taken. */ setipl((u_char)mask); + +m197beatit: + return; } -#endif /* defined(MVME187) || defined(MVME197) */ +#endif int cpu_exec_aout_makecmds(p, epp) @@ -2096,7 +2266,7 @@ regdump(struct trapframe *f) R(24),R(25),R(26),R(27),R(28),R(29)); printf("R30-31: 0x%08x 0x%08x\n",R(30),R(31)); if (cputyp == CPU_88110) { - printf("exip %x enip %x\n", f->sxip, f->snip); + printf("exip %x enip %x\n", f->exip, f->enip); } else { printf("sxip %x snip %x sfip %x\n", f->sxip, f->snip, f->sfip); } @@ -2110,45 +2280,26 @@ regdump(struct trapframe *f) dae_print((unsigned *)f); } if (longformat && cputyp != CPU_88110) { - printf("fpsr %x ", f->fpsr); - printf("fpcr %x ", f->fpcr); - printf("epsr %x ", f->epsr); - printf("ssbr %x\n", f->ssbr); - printf("fpecr %x ", f->fpecr); - printf("fphs1 %x ", f->fphs1); - printf("fpls1 %x ", f->fpls1); - printf("fphs2 %x ", f->fphs2); - printf("fpls2 %x\n", f->fpls2); - printf("fppt %x ", f->fppt); - printf("fprh %x ", f->fprh); - printf("fprl %x ", f->fprl); - printf("fpit %x\n", f->fpit); - printf("vector %d ", f->vector); - printf("mask %x ", f->mask); - printf("mode %x ", f->mode); - printf("scratch1 %x ", f->scratch1); - printf("cpu %x\n", f->cpu); + printf("fpsr %x fpcr %x epsr %x ssbr %x\n", + f->fpsr, f->fpcr, f->epsr, f->ssbr); + printf("fpecr %x fphs1 %x fpls1 %x fphs2 %x fpls2 %x\n", + f->fpecr, f->fphs1, f->fpls1, f->fphs2, f->fpls2); + printf("fppt %x fprh %x fprl %x fpit %x\n", + f->fppt, f->fprh, f->fprl, f->fpit); + printf("vector %d mask %x mode %x scratch1 %x cpu %x\n", + f->vector, f->mask, f->mode, f->scratch1, f->cpu); } #endif #ifdef M88110 - if (longformat && cputyp == CPU_197) { - printf("fpsr %x ", f->fpsr); - printf("fpcr %x ", f->fpcr); - printf("fpecr %x ", f->fpecr); - printf("epsr %x\n", f->epsr); - printf("dsap %x ", f->dmt1); - printf("dsr %x ", f->dsr); - printf("dlar %x ", f->dlar); - printf("dpar %x\n", f->dpar); - printf("isap %x ", f->dmt0); - printf("isr %x ", f->isr); - printf("ilar %x ", f->ilar); - printf("ipar %x\n", f->ipar); - printf("vector %d ", f->vector); - printf("mask %x ", f->mask); - printf("mode %x ", f->mode); - printf("scratch1 %x ", f->scratch1); - printf("cpu %x\n", f->cpu); + if (longformat && cputyp == CPU_88110) { + printf("fpsr %x fpcr %x fpecr %x epsr %x\n", + f->fpsr, f->fpcr, f->fpecr, f->epsr); + printf("dsap %x duap %x dsr %x dlar %x dpar %x\n", + f->dsap, f->duap, f->dsr, f->dlar, f->dpar); + printf("isap %x iuap %x isr %x ilar %x ipar %x\n", + f->isap, f->iuap, f->isr, f->ilar, f->ipar); + printf("vector %d mask %x mode %x scratch1 %x cpu %x\n", + f->vector, f->mask, f->mode, f->scratch1, f->cpu); } #endif #ifdef MVME188 @@ -2177,6 +2328,17 @@ mvme_bootstrap() extern void set_tcfp __P((void)); struct bugbrdid brdid; + + + /* + * Must initialize p_addr before autoconfig or + * the fault handler will get a NULL reference. + * Do this early so that we can take a data or + * instruction fault and survive it. XXX smurph + */ + proc0.p_addr = proc0paddr; + curproc = &proc0; + curpcb = &proc0paddr->u_pcb; /* zreo out the machine dependant function pointers */ bzero(&md, sizeof(struct md_p)); @@ -2209,7 +2371,7 @@ mvme_bootstrap() #endif /* MVME188 */ #ifdef MVME187 case BRD_187: - md.interrupt_func = &sbc_ext_int; + md.interrupt_func = &m187_ext_int; md.intr_mask = (u_char *)M187_IMASK; md.intr_ipl = (u_char *)M187_ILEVEL; md.intr_src = NULL; @@ -2217,7 +2379,7 @@ mvme_bootstrap() #endif /* MVME187 */ #ifdef MVME197 case BRD_197: - md.interrupt_func = &sbc_ext_int; + md.interrupt_func = &m197_ext_int; md.intr_mask = (u_char *)M197_IMASK; md.intr_ipl = (u_char *)M197_ILEVEL; md.intr_src = (u_char *)M197_ISRC; @@ -2236,6 +2398,7 @@ mvme_bootstrap() first_addr = round_page(first_addr); last_addr = size_memory(); + cmmu_parity_enable(); setup_board_config(); @@ -2272,14 +2435,6 @@ mvme_bootstrap() */ uvm_page_physload(atop(avail_start), atop(avail_end), atop(avail_start), atop(avail_end),VM_FREELIST_DEFAULT); - - /* - * Must initialize p_addr before autoconfig or - * the fault handler will get a NULL reference. - */ - proc0.p_addr = proc0paddr; - curproc = &proc0; - curpcb = &proc0paddr->u_pcb; /* Initialize cached PTEs for u-area mapping. */ save_u_area(&proc0, (vm_offset_t)proc0paddr); |