summaryrefslogtreecommitdiff
path: root/sys/arch/amiga
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1996-02-06 09:24:04 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1996-02-06 09:24:04 +0000
commitd6c3f4efc8b31ad490dabaa8ab86e39364fd932c (patch)
tree16b2668741a9730039e37cccb707185213c01872 /sys/arch/amiga
parente3d2dbe2430c1867dfa1f93af0d6216d1b01e0b2 (diff)
Added support for a new (well, I've run it locally for a year or two)
interrupt system which is a prerequisite for the Amiga ISA support. It is described in amiga/amiga/README.ints, and is enabled by adding an "options IPL_REMAP_1" in the kernel config file. Along with this change there is also some generic cleanup, like style polishing, comment corrections, making sicallbacks operate in FIFO manner and cleaning up the spl mess in param.h...
Diffstat (limited to 'sys/arch/amiga')
-rw-r--r--sys/arch/amiga/dev/clock.c38
-rw-r--r--sys/arch/amiga/dev/mfc.c3
-rw-r--r--sys/arch/amiga/dev/mgnsc.c4
-rw-r--r--sys/arch/amiga/dev/siop.c2
-rw-r--r--sys/arch/amiga/dev/zssc.c6
-rw-r--r--sys/arch/amiga/include/param.h151
6 files changed, 134 insertions, 70 deletions
diff --git a/sys/arch/amiga/dev/clock.c b/sys/arch/amiga/dev/clock.c
index 48cee820ec0..c30284cdd60 100644
--- a/sys/arch/amiga/dev/clock.c
+++ b/sys/arch/amiga/dev/clock.c
@@ -50,6 +50,7 @@
#include <amiga/amiga/device.h>
#include <amiga/amiga/custom.h>
#include <amiga/amiga/cia.h>
+#include <amiga/amiga/isr.h>
#include <amiga/dev/rtc.h>
#include <amiga/dev/zbusvar.h>
@@ -57,6 +58,8 @@
#include <sys/PROF.h>
#endif
+extern void hardclock();
+
/* the clocks run at NTSC: 715.909kHz or PAL: 709.379kHz.
We're using a 100 Hz clock. */
@@ -64,6 +67,15 @@
int amiga_clk_interval;
int eclockfreq;
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+/*
+ * The INT6 handler copies the clockframe from the stack in here as hardclock
+ * may be delayed by the IPL-remapping code. At that time the original stack
+ * location will no longer be valid.
+ */
+struct clockframe hardclock_frame;
+#endif
+
/*
* Machine-dependent clock routines.
*
@@ -137,9 +149,26 @@ clockattach(pdp, dp, auxp)
ciab.tahi = interval >> 8;
}
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+int
+clockintr ()
+{
+ /* Is it a timer A interrupt? */
+ if (ciab.icr & 1) {
+ hardclock(&hardclock_frame);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
void
cpu_initclocks()
{
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+ static struct isr isr;
+#endif
+
/*
* enable interrupts for timer A
*/
@@ -150,10 +179,17 @@ cpu_initclocks()
*/
ciab.cra = (ciab.cra & 0xc0) | 1;
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+ isr.isr_intr = clockintr;
+ isr.isr_ipl = 6;
+ isr.isr_mapped_ipl = 4;
+ add_isr(&isr);
+#else
/*
* and globally enable interrupts for ciab
*/
custom.intena = INTF_SETCLR | INTF_EXTER;
+#endif
}
setstatclockrate(hz)
@@ -213,7 +249,7 @@ setmicspertick()
/*
* set timer B in "count timer A underflows" mode
- * set tiemr A in one-shot mode
+ * set timer A in one-shot mode
*/
ciaa.crb = (ciaa.crb & 0x80) | 0x48;
ciaa.cra = (ciaa.cra & 0xc0) | 0x08;
diff --git a/sys/arch/amiga/dev/mfc.c b/sys/arch/amiga/dev/mfc.c
index 1e9639dbd19..f0c7280e93b 100644
--- a/sys/arch/amiga/dev/mfc.c
+++ b/sys/arch/amiga/dev/mfc.c
@@ -362,6 +362,9 @@ mfcattach(pdp, dp, auxp)
scc->sc_isr.isr_intr = mfcintr;
scc->sc_isr.isr_arg = scc;
scc->sc_isr.isr_ipl = 6;
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+ scc->sc_isr.isr_mapped_ipl = 3;
+#endif
add_isr(&scc->sc_isr);
/* configure ports */
diff --git a/sys/arch/amiga/dev/mgnsc.c b/sys/arch/amiga/dev/mgnsc.c
index a41f58f6fa3..acec614d184 100644
--- a/sys/arch/amiga/dev/mgnsc.c
+++ b/sys/arch/amiga/dev/mgnsc.c
@@ -129,6 +129,10 @@ mgnscattach(pdp, dp, auxp)
sc->sc_isr.isr_intr = mgnsc_dmaintr;
sc->sc_isr.isr_arg = sc;
sc->sc_isr.isr_ipl = 6;
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+ /* XXX Don't remap it yet, the driver uses a sicallback still. */
+ sc->sc_isr.isr_mapped_ipl = 6;
+#endif
add_isr (&sc->sc_isr);
/*
diff --git a/sys/arch/amiga/dev/siop.c b/sys/arch/amiga/dev/siop.c
index a572aef9390..916e02acd1e 100644
--- a/sys/arch/amiga/dev/siop.c
+++ b/sys/arch/amiga/dev/siop.c
@@ -531,7 +531,7 @@ siopinitialize(sc)
extern int shift_nosync;
/*
- * Need to check that scripts is on a long word boundary
+ * Need to check that scripts is on a long word boundary.
* Also should verify that dev doesn't span non-contiguous
* physical pages.
*/
diff --git a/sys/arch/amiga/dev/zssc.c b/sys/arch/amiga/dev/zssc.c
index 735581ce75b..36510a01ab1 100644
--- a/sys/arch/amiga/dev/zssc.c
+++ b/sys/arch/amiga/dev/zssc.c
@@ -79,7 +79,7 @@ struct cfdriver zssccd = {
DV_DULL, sizeof(struct siop_softc), NULL, 0 };
/*
- * if we are an PPI Zeus
+ * if we are a PPI Zeus
*/
int
zsscmatch(pdp, cdp, auxp)
@@ -130,6 +130,10 @@ zsscattach(pdp, dp, auxp)
sc->sc_isr.isr_intr = zssc_dmaintr;
sc->sc_isr.isr_arg = sc;
sc->sc_isr.isr_ipl = 6;
+#if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+ /* XXX Don't remap it yet, the driver uses a sicallback still. */
+ sc->sc_isr.isr_mapped_ipl = 6;
+#endif
add_isr(&sc->sc_isr);
/*
diff --git a/sys/arch/amiga/include/param.h b/sys/arch/amiga/include/param.h
index 68474492998..ca3df454583 100644
--- a/sys/arch/amiga/include/param.h
+++ b/sys/arch/amiga/include/param.h
@@ -147,86 +147,103 @@
*/
#include <machine/psl.h>
-/*
- * point to the custom.intenar and custom.intenaw respectively.
- */
-extern volatile unsigned short *amiga_intena_read, *amiga_intena_write;
-
-#if 0
-#define _debug_spl(s) \
-({ \
- register int _spl_r; \
-\
- __asm __volatile ("clrl %0; movew sr,%0; movew %1,sr" : \
- "&=d" (_spl_r) : "di" (s)); \
- if ((_spl_r&PSL_IPL) > ((s)&PSL_IPL)&&((s)&PSL_IPL)!=PSL_IPL1) \
- printf ("%s:%d:spl(%d) ==> spl(%d)!!\n",__FILE__,__LINE__, \
- ((PSL_IPL&_spl_r)>>8), ((PSL_IPL&(s))>>8)); \
- _spl_r; \
-})
-#else
-/*
- * Don't lower IPL below current IPL (unless new IPL is 6)
- */
-#define _debug_spl(s) \
-({ \
- register int _spl_r; \
-\
- __asm __volatile ("clrl %0; movew sr,%0" : \
- "&=d" (_spl_r)); \
- if ((((s)&PSL_IPL) >= PSL_IPL6) || (_spl_r&PSL_IPL) < ((s)&PSL_IPL) || ((s)&PSL_IPL) <= PSL_IPL1) \
- __asm __volatile ("movew %0,sr" : : "di" (s)); \
- _spl_r; \
-})
+#ifdef _KERNEL
+
+static __inline int
+splraise(npsl)
+ register int npsl;
+{
+ register int opsl;
+
+ __asm __volatile ("clrl %0; movew sr,%0; movew %1,sr" : "&=d" (opsl) :
+ "di" (npsl));
+ return opsl;
+}
+
+#ifdef IPL_REMAP_1
+
+extern int isr_exter_ipl;
+extern void walk_ipls __P((int, int));
+
+static __inline int
+splx(npsl)
+ register int npsl;
+{
+ register int opsl;
+
+ __asm __volatile ("clrl %0; movew sr,%0" : "=d" (opsl));
+ if ((isr_exter_ipl << 8) > (npsl & PSL_IPL))
+ walk_ipls(isr_exter_ipl, npsl);
+ __asm __volatile("movew %0,sr" : : "di" (npsl));
+ return opsl;
+}
#endif
-#define _spl_no_check(s) \
-({ \
- register int _spl_r; \
-\
- __asm __volatile ("clrl %0; movew sr,%0; movew %1,sr" : \
- "&=d" (_spl_r) : "di" (s)); \
- _spl_r; \
-})
-#if defined (DEBUGXX) /* No workee */
-#define _spl _debug_spl
+#ifndef IPL_REMAP_2
+#define splx splraise
#else
-#define _spl _spl_no_check
+
+extern int walk_ipls __P((int));
+
+static __inline int
+splx(npsl)
+ register int npsl;
+{
+ register int opsl;
+
+ /* We should maybe have a flag telling if this is needed. */
+ opsl = walk_ipls(npsl);
+ __asm __volatile("movew %0,sr" : : "di" (npsl));
+ return opsl;
+}
+
#endif
-#define spl0() _spl(PSL_S|PSL_IPL0)
-#define spl1() _spl(PSL_S|PSL_IPL1)
-#define spl2() _spl(PSL_S|PSL_IPL2)
-#define spl3() _spl(PSL_S|PSL_IPL3)
-#define spl4() _spl(PSL_S|PSL_IPL4)
-#define spl5() _spl(PSL_S|PSL_IPL5)
-#define spl6() _spl(PSL_S|PSL_IPL6)
-#define spl7() _spl(PSL_S|PSL_IPL7)
-
-#define splnone() spl0()
-#define splsoftclock() spl1()
-#define splsoftnet() spl1()
+/*
+ * Shortcuts
+ */
+#define spl1() splraise(PSL_S|PSL_IPL1)
+#define spl2() splraise(PSL_S|PSL_IPL2)
+#define spl3() splraise(PSL_S|PSL_IPL3)
+#define spl4() splraise(PSL_S|PSL_IPL4)
+#define spl5() splraise(PSL_S|PSL_IPL5)
+#define spl6() splraise(PSL_S|PSL_IPL6)
+#define spl7() splraise(PSL_S|PSL_IPL7)
+
+/*
+ * Hardware interrupt masks
+ */
#define splbio() spl3()
#define splnet() spl3()
#define spltty() spl4()
#define splimp() spl4()
-#ifndef LEV6_DEFER
-#define splclock() spl6()
-#define splstatclock() spl6()
-#define splvm() spl6()
-#define splhigh() spl7()
-#define splsched() spl7()
-#else
+#if defined(LEV6_DEFER) || defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
#define splclock() spl4()
-#define splstatclock() spl4()
-#define splvm() spl4()
-#define splhigh() spl4()
-#define splsched() spl4()
+#else
+#define splclock() spl6()
#endif
+#define splstatclock() splclock()
-#define splx(s) _spl_no_check(s)
+/*
+ * Software interrupt masks
+ *
+ * NOTE: splsoftclock() is used by hardclock() to lower the priority from
+ * clock to softclock before it calls softclock().
+ */
+#define splsoftclock() splx(PSL_S|PSL_IPL1)
+#define splsoftnet() spl1()
+#define splsofttty() spl1()
+
+/*
+ * Miscellaneous
+ */
+#if defined(LEV6_DEFER) || defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+#define splhigh() spl4()
+#else
+#define splhigh() spl7()
+#endif
+#define spl0() splx(PSL_S|PSL_IPL0)
-#ifdef _KERNEL
void delay __P((int));
void DELAY __P((int));
#endif