summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Murphree <smurph@cvs.openbsd.org>2001-12-20 06:43:24 +0000
committerSteve Murphree <smurph@cvs.openbsd.org>2001-12-20 06:43:24 +0000
commitcb6b60afca0b5cc87142ae693175dce6483ad868 (patch)
tree474a1f13f0dda83c39c4827695c6ed51eea25459
parentf60ad6e424322e24080a0a1e718325161de17b2f (diff)
MVME197 gets it's own external interrupt routine.
-rw-r--r--sys/arch/mvme88k/mvme88k/machdep.c293
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);