commit 1d34167488e56e36ad702627b17be7ac18a9db9c
Author: Damien Zammit <damien@zamaudio.com>
Date:   Sun Nov 10 16:27:42 2019 +0100

    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.

Index: gnumach/i386/i386/pic.c
===================================================================
--- gnumach.orig/i386/i386/pic.c
+++ gnumach/i386/i386/pic.c
@@ -57,7 +57,6 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
 #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
Index: gnumach/i386/i386/pic.h
===================================================================
--- gnumach.orig/i386/i386/pic.h
+++ gnumach/i386/i386/pic.h
@@ -177,10 +177,8 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
 #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__ */
Index: gnumach/i386/i386/pit.c
===================================================================
--- gnumach.orig/i386/i386/pit.c
+++ gnumach/i386/i386/pit.c
@@ -71,7 +71,6 @@ clkstart(void)
 	unsigned long s;
 
 	intpri[0] = SPLHI;
-	form_pic_mask();
 
 	s = sploff();         /* disable interrupts */
 
Index: gnumach/i386/i386/spl.S
===================================================================
--- gnumach.orig/i386/i386/spl.S
+++ gnumach/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
Index: gnumach/i386/i386at/autoconf.c
===================================================================
--- gnumach.orig/i386/i386at/autoconf.c
+++ gnumach/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");
Index: gnumach/i386/i386at/kd_mouse.c
===================================================================
--- gnumach.orig/i386/i386at/kd_mouse.c
+++ gnumach/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);
 }
 
Index: gnumach/linux/dev/arch/i386/kernel/irq.c
===================================================================
--- gnumach.orig/linux/dev/arch/i386/kernel/irq.c
+++ gnumach/linux/dev/arch/i386/kernel/irq.c
@@ -160,18 +160,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);
     }
 }
 
@@ -181,18 +178,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
@@ -816,8 +813,6 @@ init_IRQ (void)
 	}
     }
   
-  form_pic_mask ();
-  
   /*
    * Enable interrupts.
    */
@@ -856,6 +851,5 @@ restore_IRQ (void)
    */
   ivect[0] = old_clock_handler;
   intpri[0] = old_clock_pri;
-  form_pic_mask ();
 }
   
Index: gnumach/linux/dev/include/asm-i386/system.h
===================================================================
--- gnumach.orig/linux/dev/include/asm-i386/system.h
+++ gnumach/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(unsig
 #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__
 
Index: gnumach/linux/dev/init/main.c
===================================================================
--- gnumach.orig/linux/dev/init/main.c
+++ gnumach/linux/dev/init/main.c
@@ -151,7 +151,6 @@ linux_init (void)
   linux_net_emulation_init ();
 #endif
 
-  cli ();
   device_setup ();
 
 #ifdef CONFIG_PCMCIA
Index: gnumach/linux/dev/kernel/sched.c
===================================================================
--- gnumach.orig/linux/dev/kernel/sched.c
+++ gnumach/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
 }
Index: gnumach/linux/src/drivers/block/ide.c
===================================================================
--- gnumach.orig/linux/src/drivers/block/ide.c
+++ gnumach/linux/src/drivers/block/ide.c
@@ -2702,6 +2702,8 @@ static int try_to_identify (ide_drive_t
 	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 */
Index: gnumach/linux/src/drivers/scsi/NCR53c406a.c
===================================================================
--- gnumach.orig/linux/src/drivers/scsi/NCR53c406a.c
+++ gnumach/linux/src/drivers/scsi/NCR53c406a.c
@@ -525,7 +525,7 @@ NCR53c406a_detect(Scsi_Host_Template * t
     
 #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;

commit 09c207eb2e7dd63d51c1f5e2abccf2562e6fd87e
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Sun Nov 10 13:39:03 2019 +0100

    ide: Use default IRQ by default
    
    To avoid even trying to probe IRQs. Nowadays' hardware use the default
    IRQ anyway.
    
    * linux/src/drivers/block/ide.c (init_hwif_data): Set hwif->irq to
    default_irqs[index].

diff --git a/linux/src/drivers/block/ide.c b/linux/src/drivers/block/ide.c
index dc20fcba..43b12f1f 100644
--- a/linux/src/drivers/block/ide.c
+++ b/linux/src/drivers/block/ide.c
@@ -395,6 +395,7 @@ static void init_hwif_data (unsigned int index)
 	/* fill in any non-zero initial values */
 	hwif->index     = index;
 	hwif->io_base	= default_io_base[index];
+	hwif->irq	= default_irqs[index];
 	hwif->ctl_port	= hwif->io_base ? hwif->io_base+0x206 : 0x000;
 #ifdef CONFIG_BLK_DEV_HD
 	if (hwif->io_base == HD_DATA)
