#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>
#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. */
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.
*
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
*/
*/
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)
/*
* 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;
*/
#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