New framework for handling processor interrupts, derived in part from

the hp300 port.

 - Interrupts 3-6 use this immediately.  Interrupt 7 is a special case,
   and the VIA interrupts (1 and 2) will be addressed when that code is
   rototilled.

 - Modify the zs front end to register with the appropriate interrupt
   controller:  through the PSC on the AV Quadras, and direct to
   interrupt 4 on the rest.  Arrange to have the appropriate zsc_softc
   supplied to us at interrupt time.

 - Modify the direct ADB driver (and its PowerManager cousin) to call
   intr_dispatch(), rather than zshard().  XXX This is a kludge, but at
   least limits the brokenness to the ADB drivers, now.

As a side effect, this should fix PR 5590.  Thanks to Bill Studenmund for
correctly determining the cause of the problem reported there.
This commit is contained in:
scottr 1998-08-12 05:42:44 +00:00
parent 3979b06d00
commit 7d09ad09b4
7 changed files with 118 additions and 191 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.mac68k,v 1.83 1998/07/01 14:49:07 scottr Exp $
# $NetBSD: files.mac68k,v 1.84 1998/08/12 05:42:44 scottr Exp $
# mac68k-specific configuration info
@ -114,6 +114,7 @@ file arch/mac68k/mac68k/bus_space.c
file arch/mac68k/mac68k/clock.c
file arch/mac68k/mac68k/conf.c
file arch/mac68k/mac68k/disksubr.c disk
file arch/mac68k/mac68k/intr.c
file arch/mac68k/mac68k/kgdb_machdep.c kgdb
file arch/mac68k/mac68k/machdep.c
file arch/mac68k/mac68k/macrom.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: adb_direct.c,v 1.14 1998/03/29 03:50:30 scottr Exp $ */
/* $NetBSD: adb_direct.c,v 1.15 1998/08/12 05:42:44 scottr Exp $ */
/* From: adb_direct.c 2.02 4/18/97 jpw */
@ -259,7 +259,9 @@ int adb_cuda_serial = 0; /* the current packet */
extern struct mac68k_machine_S mac68k_machine;
#if 0
int zshard __P((int));
#endif
void pm_setup_adb __P((void));
void pm_check_adb_devices __P((int));
@ -692,7 +694,11 @@ adb_intr_II(void)
ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
delay(ADB_DELAY); /* yuck (don't remove) */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
if (ADB_INTR_IS_ON)
intr_on = 1; /* save for later */
@ -739,7 +745,11 @@ switch_start:
adbActionState = ADB_ACTION_IN;
}
delay(ADB_DELAY);
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
goto switch_start;
break;
case ADB_ACTION_IDLE:
@ -1224,7 +1234,11 @@ switch_start:
ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
delay(ADB_DELAY); /* delay */
ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
break;
case ADB_ACTION_IN:
@ -1238,7 +1252,11 @@ switch_start:
ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
delay(ADB_DELAY); /* delay */
ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
if (1 == ending) { /* end of message? */
ADB_SET_STATE_INACTIVE(); /* signal end of frame */
@ -1286,7 +1304,11 @@ switch_start:
adbActionState = ADB_ACTION_OUT; /* set next state */
delay(ADB_DELAY); /* delay */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
if (ADB_INTR_IS_ON) { /* ADB intr low during
* write */
@ -1327,13 +1349,21 @@ switch_start:
adbWriteDelay = 1; /* must retry when done with
* read */
delay(ADB_DELAY); /* delay */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
goto switch_start; /* process next state right
* now */
break;
}
delay(ADB_DELAY); /* required delay */
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data

View File

@ -1,4 +1,4 @@
/* $NetBSD: pm_direct.c,v 1.5 1998/03/29 03:50:30 scottr Exp $ */
/* $NetBSD: pm_direct.c,v 1.6 1998/08/12 05:42:44 scottr Exp $ */
/*
* Copyright (C) 1997 Takashi Hamada
@ -221,10 +221,12 @@ struct adbCommand {
extern void adb_pass_up __P((struct adbCommand *));
#if 0
/*
* Define the external functions
*/
extern int zshard __P((int)); /* from zs.c */
#endif
#ifdef ADB_DEBUG
/*
@ -304,7 +306,11 @@ pm_wait_busy(delay)
{
while (PM_IS_ON) {
#ifdef PM_GRAB_SI
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
#endif
if ((--delay) < 0)
return 1; /* timeout */
@ -322,7 +328,11 @@ pm_wait_free(delay)
{
while (PM_IS_OFF) {
#ifdef PM_GRAB_SI
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
#endif
if ((--delay) < 0)
return 0; /* timeout */
@ -1038,7 +1048,11 @@ pm_adb_op(buffer, compRout, data, command)
if ((via_reg(VIA1, vIFR) & 0x10) == 0x10)
pm_intr();
#ifdef PM_GRAB_SI
#if 0
zshard(0); /* grab any serial interrupts */
#else
(void)intr_dispatch(0x70);
#endif
#endif
if ((--delay) < 0)
return 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.23 1998/07/04 22:18:27 jonathan Exp $ */
/* $NetBSD: zs.c,v 1.24 1998/08/12 05:42:45 scottr Exp $ */
/*
* Copyright (c) 1996-1998 Bill Studenmund
@ -69,6 +69,7 @@
#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/psc.h>
#include <machine/viareg.h>
#include <dev/cons.h>
@ -395,6 +396,13 @@ zsc_attach(parent, self, aux)
}
}
if (current_mac_model->class == MACH_CLASSAV) {
add_psc_lev4_intr(2, zshard, zsc);
add_psc_lev4_intr(3, zshard, zsc);
} else {
intr_establish(zshard, zsc, ZSHARD_PRI);
}
/* Now safe to enable interrupts. */
/*
@ -458,38 +466,34 @@ zsmd_setclock(cs)
static int zssoftpending;
/*
* Our ZS chips all share a common, autovectored interrupt,
* so we have to look at all of them on each interrupt.
* Do the minimum work to pull data off of the chip and queue it up
* for later processing.
*/
int
zshard(arg)
void *arg;
{
struct zsc_softc *zsc;
int unit, rval;
struct zsc_softc *zsc = (struct zsc_softc *)arg;
int rval;
if (zsc == NULL)
return 0;
rval = 0;
for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
zsc = zsc_cd.cd_devs[unit];
if (zsc == NULL)
continue;
rval |= zsc_intr_hard(zsc);
if ((zsc->zsc_cs[0]->cs_softreq) ||
(zsc->zsc_cs[1]->cs_softreq))
{
/* zsc_req_softint(zsc); */
/* We are at splzs here, so no need to lock. */
if (zssoftpending == 0) {
zssoftpending = 1;
setsoftserial();
}
rval |= zsc_intr_hard(zsc);
if ((zsc->zsc_cs[0]->cs_softreq) || (zsc->zsc_cs[1]->cs_softreq)) {
/* zsc_req_softint(zsc); */
/* We are at splzs here, so no need to lock. */
if (zssoftpending == 0) {
zssoftpending = 1;
setsoftserial();
}
}
return (rval);
}
/*
* Similar scheme as for zshard (look at all of them)
* Look at all of the zsc softint queues.
*/
int
zssoft(arg)

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.s,v 1.104 1998/08/12 02:36:37 scottr Exp $ */
/* $NetBSD: locore.s,v 1.105 1998/08/12 05:42:45 scottr Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -820,6 +820,9 @@ Lbrkpt3:
* Level 7: NMIs: parity errors?, RESET button
*/
#define INTERRUPT_SAVEREG moveml #0xC0C0,sp@-
#define INTERRUPT_RESTOREREG moveml sp@+,#0x0303
ENTRY_NOPROFILE(spurintr)
addql #1,_C_LABEL(intrcnt)+0
#if defined(UVM)
@ -862,79 +865,21 @@ ENTRY_NOPROFILE(lev2intr)
#endif
jra _ASM_LABEL(rei)
ENTRY_NOPROFILE(lev3intr)
addql #1,_C_LABEL(intrcnt)+24
clrl sp@-
moveml #0xFFFF,sp@-
movl sp, sp@-
movl _C_LABEL(lev3_intrvec),a2
jbsr a2@
ENTRY_NOPROFILE(intrhand) /* levels 3 through 6 */
INTERRUPT_SAVEREG
movw sp@(22),sp@- | push exception vector info
clrw sp@-
jbsr _C_LABEL(intr_dispatch) | call dispatch routine
addql #4,sp
moveml sp@+, #0xFFFF
addql #4,sp
#if defined(UVM)
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
#else
addql #1,_C_LABEL(cnt)+V_INTR
#endif
jra _ASM_LABEL(rei)
ENTRY_NOPROFILE(lev4intr)
addql #1,_C_LABEL(intrcnt)+12
clrl sp@-
moveml #0xFFFF,sp@-
movl sp, sp@-
movl _C_LABEL(lev4_intrvec),a2
jbsr a2@
addql #4,sp
tstl d0
beq normal_rei
moveml sp@+, #0xFFFF
addql #4,sp
rte
#if 1 /* XXX */
tstl d0 | XXX hack for the MACE driver!
beq normal_rei | XXX if we handled the interrupt,
INTERRUPT_RESTOREREG | XXX restore registers and return
rte | XXX immediately.
normal_rei:
moveml sp@+, #0xFFFF
addql #4,sp
#if defined(UVM)
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
#else
addql #1,_C_LABEL(cnt)+V_INTR
#endif
jra _ASM_LABEL(rei)
ENTRY_NOPROFILE(lev5intr)
addql #1,_C_LABEL(intrcnt)+28
clrl sp@-
moveml #0xFFFF,sp@-
movl sp, sp@-
movl _C_LABEL(lev5_intrvec),a2
jbsr a2@
addql #4,sp
moveml sp@+, #0xFFFF
addql #4,sp
#if defined(UVM)
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
#else
addql #1,_C_LABEL(cnt)+V_INTR
#endif
jra _ASM_LABEL(rei)
ENTRY_NOPROFILE(lev6intr)
addql #1,_C_LABEL(intrcnt)+32
clrl sp@-
moveml #0xFFFF,sp@-
movl sp, sp@-
movl _C_LABEL(lev6_intrvec),a2
jbsr a2@
addql #4,sp
moveml sp@+, #0xFFFF
addql #4,sp
#if defined(UVM)
addql #1,_C_LABEL(uvmexp)+UVMEXP_INTRS
#else
addql #1,_C_LABEL(cnt)+V_INTR
#endif
jra _ASM_LABEL(rei)
INTERRUPT_RESTOREREG
jra _ASM_LABEL(rei) | all done
ENTRY_NOPROFILE(lev7intr)
addql #1,_C_LABEL(intrcnt)+16

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.208 1998/08/12 02:36:38 scottr Exp $ */
/* $NetBSD: machdep.c,v 1.209 1998/08/12 05:42:45 scottr Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -78,10 +78,6 @@
#include "opt_adb.h"
#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_atalk.h"
#include "opt_iso.h"
#include "opt_ns.h"
#include "opt_uvm.h"
#include "opt_compat_netbsd.h"
#include "zsc.h"
@ -1097,56 +1093,6 @@ straytrap(pc, evec)
#endif
}
void arpintr __P((void));
void ipintr __P((void));
void atintr __P((void));
void nsintr __P((void));
void clnlintr __P((void));
void pppintr __P((void));
void netintr __P((void));
void
netintr()
{
#ifdef INET
#if NARP > 0
if (netisr & (1 << NETISR_ARP)) {
netisr &= ~(1 << NETISR_ARP);
arpintr();
}
#endif
if (netisr & (1 << NETISR_IP)) {
netisr &= ~(1 << NETISR_IP);
ipintr();
}
#endif
#ifdef NETATALK
if (netisr & (1 << NETISR_ATALK)) {
netisr &= ~(1 << NETISR_ATALK);
atintr();
}
#endif
#ifdef NS
if (netisr & (1 << NETISR_NS)) {
netisr &= ~(1 << NETISR_NS);
nsintr();
}
#endif
#ifdef ISO
if (netisr & (1 << NETISR_ISO)) {
netisr &= ~(1 << NETISR_ISO);
clnlintr();
}
#endif
#include "ppp.h"
#if NPPP > 0
if (netisr & (1 << NETISR_PPP)) {
netisr &= ~(1 << NETISR_PPP);
pppintr();
}
#endif
}
/*
* Level 7 interrupts can be caused by the keyboard or parity errors.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: psc.c,v 1.4 1998/04/24 05:27:26 scottr Exp $ */
/* $NetBSD: psc.c,v 1.5 1998/08/12 05:42:46 scottr Exp $ */
/*-
* Copyright (c) 1997 David Huang <khym@bga.com>
@ -38,30 +38,22 @@
#include <machine/cpu.h>
#include <machine/psc.h>
void psc_lev3_intr __P((struct frame *));
int psc_lev3_intr __P((void *));
static void psc_lev3_noint __P((void *));
int psc_lev4_intr __P((struct frame *));
int psc_lev4_intr __P((void *));
static int psc_lev4_noint __P((void *));
void psc_lev5_intr __P((struct frame *));
int psc_lev5_intr __P((void *));
static void psc_lev5_noint __P((void *));
void psc_lev6_intr __P((struct frame *));
int psc_lev6_intr __P((void *));
static void psc_lev6_noint __P((void *));
void psc_spurintr __P((struct frame *));
void (*lev3_intrvec) __P((struct frame *));
int (*lev4_intrvec) __P((struct frame *));
void (*lev5_intrvec) __P((struct frame *));
void (*lev6_intrvec) __P((struct frame *));
extern int zshard __P((void *)); /* from zs.c */
void (*psc3_ihandler) __P((void *)) = psc_lev3_noint;
void *psc3_iarg;
int (*psc4_itab[4]) __P((void *)) = {
psc_lev4_noint, /* 0 */
zshard, /* 1 */
zshard, /* 2 */
psc_lev4_noint, /* 1 */
psc_lev4_noint, /* 2 */
psc_lev4_noint /* 3 */
};
@ -95,32 +87,21 @@ void
psc_init()
{
/*
* Only Quadra AVs have a PSC. On other machines, point the
* level 4 interrupt to zshard(), and levels 3, 5, and 6 to
* psc_spurintr().
* Only Quadra AVs have a PSC.
*/
if (current_mac_model->class == MACH_CLASSAV) {
lev3_intrvec = psc_lev3_intr;
lev4_intrvec = psc_lev4_intr;
lev5_intrvec = psc_lev5_intr;
lev6_intrvec = psc_lev6_intr;
intr_establish(psc_lev3_intr, NULL, 3);
intr_establish(psc_lev4_intr, NULL, 4);
intr_establish(psc_lev5_intr, NULL, 5);
intr_establish(psc_lev6_intr, NULL, 6);
psc_reg1(PSC_LEV3_IER) = 0x01; /* disable level 3 interrupts */
psc_reg1(PSC_LEV4_IER) = 0x09; /* disable level 4 interrupts */
psc_reg1(PSC_LEV4_IER) = 0x86; /* except for SCC */
psc_reg1(PSC_LEV5_IER) = 0x03; /* disable level 5 interrupts */
psc_reg1(PSC_LEV6_IER) = 0x07; /* disable level 6 interrupts */
} else {
lev3_intrvec = lev5_intrvec = lev6_intrvec = psc_spurintr;
lev4_intrvec = (int (*)(struct frame *))zshard;
}
}
void
psc_spurintr(fp)
struct frame *fp;
{
}
int
add_psc_lev3_intr(handler, arg)
void (*handler)(void *);
@ -144,9 +125,9 @@ remove_psc_lev3_intr()
return add_psc_lev3_intr(psc_lev3_noint, (void *)0);
}
void
psc_lev3_intr(fp)
struct frame *fp;
int
psc_lev3_intr(arg)
void *arg;
{
u_int8_t intbits;
@ -156,6 +137,8 @@ psc_lev3_intr(fp)
if (intbits)
psc3_ihandler(psc3_iarg);
return 0;
}
static void
@ -166,8 +149,8 @@ psc_lev3_noint(arg)
}
int
psc_lev4_intr(fp)
struct frame *fp;
psc_lev4_intr(arg)
void *arg;
{
u_int8_t intbits, bitnum;
u_int mask;
@ -223,9 +206,9 @@ psc_lev4_noint(arg)
return 0;
}
void
psc_lev5_intr(fp)
struct frame *fp;
int
psc_lev5_intr(arg)
void *arg;
{
u_int8_t intbits, bitnum;
u_int mask;
@ -241,6 +224,8 @@ psc_lev5_intr(fp)
psc5_itab[bitnum](psc5_iarg[bitnum]);
mask <<= 1;
} while (intbits >= mask && ++bitnum);
return 0;
}
int
@ -278,9 +263,9 @@ psc_lev5_noint(arg)
printf("psc_lev5_noint: device %d\n", (int)arg);
}
void
psc_lev6_intr(fp)
struct frame *fp;
int
psc_lev6_intr(arg)
void *arg;
{
u_int8_t intbits, bitnum;
u_int mask;
@ -296,6 +281,8 @@ psc_lev6_intr(fp)
psc6_itab[bitnum](psc6_iarg[bitnum]);
mask <<= 1;
} while (intbits >= mask && ++bitnum);
return 0;
}
int