summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2019-11-10 16:27:42 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2019-11-10 16:28:50 +0100
commit1d34167488e56e36ad702627b17be7ac18a9db9c (patch)
tree9f107a4647490b81793e6548d0e0da444f742584
parent09c207eb2e7dd63d51c1f5e2abccf2562e6fd87e (diff)
simplify interrupt handling
We have removed spl levels, now remove the machinery to manage different PIC masks according to levels. Only keep machinery to disable interrupts whatever the level. * i386/i386/pic.c (pic_mask): Remove array. (picinit): Do not form PIC mask. Set initial PIC mask to 0. (form_pic_mask): Remove function. * i386/i386/pic.h (form_pic_mask, pic_mask): Remove declarations. * i386/i386/spl.S (SETMASK): Remove macro. (XEN_SETMASK): Add macro, containing the Xen version of SETMASK. (spl0, splx_cli, spl) [MACH_XEN]: Call XEN_SETMASK instead of SETMASK. * i386/i386/pit.c (clkstart): Do not call form_pic_mask. * i386/i386at/autoconf.c (take_dev_irq, take_ctlr_irq): Likewise. * i386/i386at/kd_mouse.c (kd_mouse_open, kd_mouse_close): Likewise. * linux/dev/arch/i386/kernel/irq.c (mask_irq, unmask_irq): Directly update curr_pic_mask without using pic_mask array. (init_IRQ, restore_IRQ): do not call form_pic_mask. * linux/dev/include/asm-i386/system.h: Include <i386/ipl.h>. (__save_flags, __restore_flags): Use curr_ipl and splx instead of hardware flags. * linux/dev/init/main.c (linux_init): Do not call cli. * linux/dev/kernel/sched.c (linux_timer_intr): Do not use pic_mask. * linux/src/drivers/block/ide.c (try_to_identify): Disable irq probing. * linux/src/drivers/scsi/NCR53c406a.c (NCR53c406a_detect): Disable irq probing.
-rw-r--r--i386/i386/pic.c89
-rw-r--r--i386/i386/pic.h2
-rw-r--r--i386/i386/pit.c1
-rw-r--r--i386/i386/spl.S47
-rw-r--r--i386/i386at/autoconf.c2
-rw-r--r--i386/i386at/kd_mouse.c2
-rw-r--r--linux/dev/arch/i386/kernel/irq.c26
-rw-r--r--linux/dev/include/asm-i386/system.h8
-rw-r--r--linux/dev/init/main.c1
-rw-r--r--linux/dev/kernel/sched.c2
-rw-r--r--linux/src/drivers/block/ide.c2
-rw-r--r--linux/src/drivers/scsi/NCR53c406a.c2
12 files changed, 51 insertions, 133 deletions
diff --git a/i386/i386/pic.c b/i386/i386/pic.c
index e8c881af..0c2e2bc8 100644
--- a/i386/i386/pic.c
+++ b/i386/i386/pic.c
@@ -57,7 +57,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <i386/pio.h>
spl_t curr_ipl;
-int pic_mask[NSPL];
int curr_pic_mask;
int iunit[NINTR] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
@@ -72,33 +71,18 @@ u_short PICM_ICW4, PICS_ICW4 ;
/*
** picinit() - This routine
** * Establishes a table of interrupt vectors
-** * Establishes a table of interrupt priority levels
-** * Establishes a table of interrupt masks to be put
-** in the PICs.
** * Establishes location of PICs in the system
+** * Unmasks all interrupts in the PICs
** * Initialises them
**
** At this stage the interrupt functionality of this system should be
-** coplete.
-**
+** complete.
*/
-
/*
-** 1. First we form a table of PIC masks - rather then calling form_pic_mask()
-** each time there is a change of interrupt level - we will form a table
-** of pic masks, as there are only 7 interrupt priority levels.
-**
-** 2. The next thing we must do is to determine which of the PIC interrupt
-** request lines have to be masked out, this is done by calling
-** form_pic_mask() with a (int_lev) of zero, this will find all the
-** interrupt lines that have priority 0, (ie to be ignored).
-** Then we split this up for the master/slave PICs.
-**
-** 2. Initialise the PICs , master first, then the slave.
-** All the register field definitions are described in pic_jh.h, also
-** the settings of these fields for the various registers are selected.
-**
+** Initialise the PICs , master first, then the slave.
+** All the register field definitions are described in pic.h also
+** the settings of these fields for the various registers are selected.
*/
void
@@ -108,23 +92,14 @@ picinit(void)
asm("cli");
/*
- ** 1. Form pic mask table
- */
-#if 0
- printf (" Let the console driver screw up this line ! \n");
-#endif
-
- form_pic_mask();
-
- /*
- ** 1a. Select current SPL.
+ ** 0. Initialise the current level to match cli()
*/
curr_ipl = SPLHI;
- curr_pic_mask = pic_mask[SPLHI];
+ curr_pic_mask = 0;
/*
- ** 2. Generate addresses to each PIC port.
+ ** 1. Generate addresses to each PIC port.
*/
master_icw = PIC_MASTER_ICW;
@@ -133,7 +108,7 @@ picinit(void)
slaves_ocw = PIC_SLAVE_OCW;
/*
- ** 3. Select options for each ICW and each OCW for each PIC.
+ ** 2. Select options for each ICW and each OCW for each PIC.
*/
PICM_ICW1 =
@@ -164,9 +139,8 @@ picinit(void)
PICM_OCW3 = (OCW_TEMPLATE | READ_NEXT_RD | READ_IR_ONRD );
PICS_OCW3 = (OCW_TEMPLATE | READ_NEXT_RD | READ_IR_ONRD );
-
/*
- ** 4. Initialise master - send commands to master PIC
+ ** 3. Initialise master - send commands to master PIC
*/
outb ( master_icw, PICM_ICW1 );
@@ -178,7 +152,7 @@ picinit(void)
outb ( master_icw, PICM_OCW3 );
/*
- ** 5. Initialise slave - send commands to slave PIC
+ ** 4. Initialise slave - send commands to slave PIC
*/
outb ( slaves_icw, PICS_ICW1 );
@@ -191,49 +165,10 @@ picinit(void)
outb ( slaves_icw, PICS_OCW3 );
/*
- ** 6. Initialise interrupts
+ ** 5. Initialise interrupts
*/
outb ( master_ocw, PICM_OCW1 );
-#if 0
- printf(" spl set to %x \n", curr_pic_mask);
-#endif
-
-}
-
-
-/*
-** form_pic_mask(int_lvl)
-**
-** For a given interrupt priority level (int_lvl), this routine goes out
-** and scans through the interrupt level table, and forms a mask based on the
-** entries it finds there that have the same or lower interrupt priority level
-** as (int_lvl). It returns a 16-bit mask which will have to be split up between
-** the 2 pics.
-**
-*/
-
-#if defined(AT386)
-#define SLAVEMASK (0xFFFF ^ SLAVE_ON_IR2)
-#endif /* defined(AT386) */
-
-#define SLAVEACTV 0xFF00
-
-void
-form_pic_mask(void)
-{
- unsigned int i, j, bit, mask;
-
- for (i=SPL0; i < NSPL; i++) {
- for (j=0x00, bit=0x01, mask = 0; j < NINTR; j++, bit<<=1)
- if (intpri[j] <= i)
- mask |= bit;
-
- if ((mask & SLAVEACTV) != SLAVEACTV )
- mask &= SLAVEMASK;
-
- pic_mask[i] = mask;
- }
}
void
diff --git a/i386/i386/pic.h b/i386/i386/pic.h
index 80bf65d6..1d224a44 100644
--- a/i386/i386/pic.h
+++ b/i386/i386/pic.h
@@ -177,10 +177,8 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define READ_IS_ONRD 0x01
#ifndef __ASSEMBLER__
-extern void form_pic_mask (void);
extern void picinit (void);
extern int curr_pic_mask;
-extern int pic_mask[];
extern void prtnull(int unit);
extern void intnull(int unit);
#endif /* __ASSEMBLER__ */
diff --git a/i386/i386/pit.c b/i386/i386/pit.c
index f0978088..bb6a4f79 100644
--- a/i386/i386/pit.c
+++ b/i386/i386/pit.c
@@ -76,7 +76,6 @@ clkstart(void)
return;
intpri[0] = SPLHI;
- form_pic_mask();
s = sploff(); /* disable interrupts */
diff --git a/i386/i386/spl.S b/i386/i386/spl.S
index 20a80766..215142c9 100644
--- a/i386/i386/spl.S
+++ b/i386/i386/spl.S
@@ -19,7 +19,6 @@
#include <mach/machine/asm.h>
#include <i386/ipl.h>
-#include <i386/pic.h>
#include <i386/i386asm.h>
#include <i386/xen.h>
@@ -30,20 +29,9 @@
#endif
/*
- * Program PICs with mask in %eax.
+ * Program XEN evt masks from %eax.
*/
-#ifndef MACH_XEN
-#define SETMASK() \
- cmpl EXT(curr_pic_mask),%eax; \
- je 9f; \
- outb %al,$(PIC_MASTER_OCW); \
- movl %eax,EXT(curr_pic_mask); \
- movb %ah,%al; \
- outb %al,$(PIC_SLAVE_OCW); \
-9:
-#else /* MACH_XEN */
-#define pic_mask int_mask
-#define SETMASK() \
+#define XEN_SETMASK() \
pushl %ebx; \
movl %eax,%ebx; \
xchgl %eax,hyp_shared_info+EVTMASK; \
@@ -55,7 +43,6 @@
lock orl $1,hyp_shared_info+CPU_PENDING_SEL; /* Yes, activate it */ \
movb $1,hyp_shared_info+CPU_PENDING; \
9:
-#endif /* MACH_XEN */
ENTRY(spl0)
mb;
@@ -90,9 +77,11 @@ ENTRY(spl0)
cmpl $(SPL0),EXT(curr_ipl) /* are we at spl0? */
je 1f /* yes, all done */
movl $(SPL0),EXT(curr_ipl) /* set ipl */
- movl EXT(pic_mask)+SPL0*4,%eax
- /* get PIC mask */
- SETMASK() /* program PICs with new mask */
+#ifdef MACH_XEN
+ movl EXT(int_mask)+SPL0*4,%eax
+ /* get xen mask */
+ XEN_SETMASK() /* program xen evts */
+#endif
1:
sti /* enable interrupts */
popl %eax /* return previous mask */
@@ -129,9 +118,9 @@ Entry(splhi)
ENTRY(spl7)
mb;
/* just clear IF */
- movl $SPL7,%eax
- xchgl EXT(curr_ipl),%eax
cli
+ movl $SPL7,%eax
+ xchgl EXT(curr_ipl),%eax
ret
ENTRY(splx)
@@ -202,9 +191,11 @@ splx_cli:
cmpl EXT(curr_ipl),%edx /* same ipl as current? */
je 1f /* yes, all done */
movl %edx,EXT(curr_ipl) /* set ipl */
- movl EXT(pic_mask)(,%edx,4),%eax
- /* get PIC mask */
- SETMASK() /* program PICs with new mask */
+#ifdef MACH_XEN
+ movl EXT(int_mask)(,%edx,4),%eax
+ /* get int mask */
+ XEN_SETMASK() /* program xen evts with new mask */
+#endif
1:
ret
@@ -229,11 +220,15 @@ spl:
#endif /* (MACH_KDB || MACH_TTD) && !MACH_XEN */
cmpl $SPL7,%edx /* spl7? */
je EXT(spl7) /* yes, handle specially */
- movl EXT(pic_mask)(,%edx,4),%eax
- /* get PIC mask */
+#ifdef MACH_XEN
+ movl EXT(int_mask)(,%edx,4),%eax
+ /* get int mask */
+#endif
cli /* disable interrupts */
xchgl EXT(curr_ipl),%edx /* set ipl */
- SETMASK() /* program PICs with new mask */
+#ifdef MACH_XEN
+ XEN_SETMASK() /* program PICs with new mask */
+#endif
sti /* enable interrupts */
movl %edx,%eax /* return previous ipl */
ret
diff --git a/i386/i386at/autoconf.c b/i386/i386at/autoconf.c
index 908c3ec0..6ed2270c 100644
--- a/i386/i386at/autoconf.c
+++ b/i386/i386at/autoconf.c
@@ -130,7 +130,6 @@ void take_dev_irq(
iunit[pic] = dev->unit;
ivect[pic] = dev->intr;
intpri[pic] = (int)dev->sysdep;
- form_pic_mask();
} else {
printf("The device below will clobber IRQ %d.\n", pic);
printf("You have two devices at the same IRQ.\n");
@@ -151,7 +150,6 @@ void take_ctlr_irq(
iunit[pic] = ctlr->unit;
ivect[pic] = ctlr->intr;
intpri[pic] = (int)ctlr->sysdep;
- form_pic_mask();
} else {
printf("The device below will clobber IRQ %d.\n", pic);
printf("You have two devices at the same IRQ. This won't work.\n");
diff --git a/i386/i386at/kd_mouse.c b/i386/i386at/kd_mouse.c
index 20a8c88c..05280055 100644
--- a/i386/i386at/kd_mouse.c
+++ b/i386/i386at/kd_mouse.c
@@ -228,7 +228,6 @@ kd_mouse_open(
ivect[mouse_pic] = kdintr;
oldspl = intpri[mouse_pic];
intpri[mouse_pic] = SPL6;
- form_pic_mask();
splx(s);
}
@@ -291,7 +290,6 @@ kd_mouse_close(
ivect[mouse_pic] = oldvect;
intpri[mouse_pic] = oldspl;
- form_pic_mask();
splx(s);
}
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index a02e9582..596dae6b 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -128,18 +128,15 @@ linux_intr (int irq)
static inline void
mask_irq (unsigned int irq_nr)
{
- int i;
-
- for (i = 0; i < intpri[irq_nr]; i++)
- pic_mask[i] |= 1 << irq_nr;
+ int new_pic_mask = curr_pic_mask | 1 << irq_nr;
- if (curr_pic_mask != pic_mask[curr_ipl])
+ if (curr_pic_mask != new_pic_mask)
{
- curr_pic_mask = pic_mask[curr_ipl];
+ curr_pic_mask = new_pic_mask;
if (irq_nr < 8)
- outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
+ outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
else
- outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
+ outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
}
}
@@ -149,18 +146,18 @@ mask_irq (unsigned int irq_nr)
static inline void
unmask_irq (unsigned int irq_nr)
{
- int mask, i;
+ int mask;
+ int new_pic_mask;
mask = 1 << irq_nr;
if (irq_nr >= 8)
mask |= 1 << 2;
- for (i = 0; i < intpri[irq_nr]; i++)
- pic_mask[i] &= ~mask;
+ new_pic_mask = curr_pic_mask & ~mask;
- if (curr_pic_mask != pic_mask[curr_ipl])
+ if (curr_pic_mask != new_pic_mask)
{
- curr_pic_mask = pic_mask[curr_ipl];
+ curr_pic_mask = new_pic_mask;
if (irq_nr < 8)
outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
else
@@ -737,8 +734,6 @@ init_IRQ (void)
}
}
- form_pic_mask ();
-
/*
* Enable interrupts.
*/
@@ -777,6 +772,5 @@ restore_IRQ (void)
*/
ivect[0] = old_clock_handler;
intpri[0] = old_clock_pri;
- form_pic_mask ();
}
diff --git a/linux/dev/include/asm-i386/system.h b/linux/dev/include/asm-i386/system.h
index f26a33e7..41eb65a4 100644
--- a/linux/dev/include/asm-i386/system.h
+++ b/linux/dev/include/asm-i386/system.h
@@ -1,6 +1,8 @@
#ifndef __ASM_SYSTEM_H
#define __ASM_SYSTEM_H
+#include <i386/ipl.h> /* curr_ipl, splx */
+
#include <asm/segment.h>
/*
@@ -223,10 +225,8 @@ static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
#define mb() __asm__ __volatile__ ("" : : :"memory")
#define __sti() __asm__ __volatile__ ("sti": : :"memory")
#define __cli() __asm__ __volatile__ ("cli": : :"memory")
-#define __save_flags(x) \
-__asm__ __volatile__("pushf ; pop %0" : "=r" (x): /* no input */ :"memory")
-#define __restore_flags(x) \
-__asm__ __volatile__("push %0 ; popf": /* no output */ :"g" (x):"memory")
+#define __save_flags(x) (x = ((curr_ipl > 0) ? 0 : (1 << 9)))
+#define __restore_flags(x) splx((x & (1 << 9)) ? 0 : 7)
#ifdef __SMP__
diff --git a/linux/dev/init/main.c b/linux/dev/init/main.c
index 3740c12c..6d853957 100644
--- a/linux/dev/init/main.c
+++ b/linux/dev/init/main.c
@@ -151,7 +151,6 @@ linux_init (void)
linux_net_emulation_init ();
#endif
- cli ();
device_setup ();
#ifdef CONFIG_PCMCIA
diff --git a/linux/dev/kernel/sched.c b/linux/dev/kernel/sched.c
index 87906a45..2a9eeb3f 100644
--- a/linux/dev/kernel/sched.c
+++ b/linux/dev/kernel/sched.c
@@ -622,6 +622,6 @@ linux_timer_intr (void)
mark_bh (TQUEUE_BH);
#if 0
if (linux_timer_print)
- printf ("linux_timer_intr: pic_mask[0] %x\n", pic_mask[0]);
+ printf ("linux_timer_intr: hello\n");
#endif
}
diff --git a/linux/src/drivers/block/ide.c b/linux/src/drivers/block/ide.c
index 43b12f1f..170e4e13 100644
--- a/linux/src/drivers/block/ide.c
+++ b/linux/src/drivers/block/ide.c
@@ -2703,6 +2703,8 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
int irq_off;
if (!HWIF(drive)->irq) { /* already got an IRQ? */
+ printk("%s: Not probing legacy IRQs)\n", drive->name);
+ return 2;
probe_irq_off(probe_irq_on()); /* clear dangling irqs */
irqs_on = probe_irq_on(); /* start monitoring irqs */
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
diff --git a/linux/src/drivers/scsi/NCR53c406a.c b/linux/src/drivers/scsi/NCR53c406a.c
index 9f2de9a0..7745f5ad 100644
--- a/linux/src/drivers/scsi/NCR53c406a.c
+++ b/linux/src/drivers/scsi/NCR53c406a.c
@@ -525,7 +525,7 @@ NCR53c406a_detect(Scsi_Host_Template * tpnt){
#ifndef IRQ_LEV
if (irq_level < 0) { /* LILO override if >= 0*/
- irq_level=irq_probe();
+ irq_level = -1; // XXX No probing irq_probe();
if (irq_level < 0) { /* Trouble */
printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
return 0;