Subject: port-amiga/2034: An optional interruptsystem is needed for the Amiga ISA support
To: None <gnats-bugs@NetBSD.ORG>
From: Niklas Hallqvist <niklas@filippa.appli.se>
List: netbsd-bugs
Date: 02/06/1996 11:54:23
>Number:         2034
>Category:       port-amiga
>Synopsis:       An optional interruptsystem is needed for the Amiga ISA support
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Feb  6 06:50:02 1996
>Last-Modified:
>Originator:     Niklas Hallqvist
>Organization:
	Applitron Datasystem AB
>Release:        951218
>Environment:
System: NetBSD filippa.appli.se 1.1_ALPHA NetBSD 1.1_ALPHA (FILIPPA) #562: Mon Dec 11 19:15:43 MET 1995 root@filippa.appli.se:/u3/newex/sys/arch/amiga/compile/FILIPPA amiga


>Description:
	ISA-bridges for Amiga present ISA interrupts at IPL6, which is known
	to be bad, as most of these need to be handled at much lower IPLs.
	Commonly this is handled by just collecting context info and acking
	the interrupt and then scheduling a callback at softint IPL.  In the
	context of ISA drivers this is not feasible with less than rewriting
	the (to-be) MI drivers.  I propose another interrupt sytem in this PR
	that by trickery inspired from LEV6_DEFER (Markus Wild's infamous hack)
	which should be selectable via a compile time option: IPL_REMAP_1.
	Read amiga/amiga/README.ints for details.

>How-To-Repeat:
	Try writing an ISA framework which uses the existing ISA driver sources
	that works with the current interrupt system

>Fix:
	Below is the patch I've checked in to openbsd, together with the commit
	message I used, I hope it's useful:

	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...

Index: src/sys/arch/amiga/amiga/README.ints
*** /dev/null   Tue Feb  6 10:49:26 1996
--- src/sys/arch/amiga/amiga/README.ints        Sat Feb  3 15:40:10 1996
***************
*** 0 ****
--- 1,48 ----
+ There are four different interruptsystems currently supported (well
+ only three, really) in the kernel.  They are all mutual exclusive:
+ 
+ 1     Default
+ 
+       Requires no kernel compiletime options to be set in the
+       config-file.  The default interrupt system is characterized by
+       never fiddling with the interrupt levels during service of
+       interrupts.  Drivers that want to can explicitly schedule
+       softint or VBL callbacks, but that is all.
+ 
+ 2     LEV6_DEFER
+ 
+       Requires "options LEV6_DEFER" to be specified in the kernel
+       config-file.  This will defer level 6 interrupts to level 4 by
+       temporarily blocking level 6 interrupts via the Amiga custom
+       interrupt controller and set the AUD3 interrupt bit in that
+       same chip.  This will imply a level 4 interrupt to be
+       schudled.  In that handler after the level 6 interrupt has
+       been serviced, IPL 6 is unblocked again.  This will have
+       positive effect on interrupts coming in at IPL 5, specifically
+       the serial recieve interrupt.  A potential trouble area is
+       audio when using that fourth channel, that is something to
+       check when someone gets the time.  This clever hack was done
+       by Markus Wild.
+ 
+ 3     IPL_REMAP_1
+ 
+       Enabled by "options IPL_REMAP_1" in the config-file.  With the
+       arrival of ISA-bus bridges, it became appearant that
+       interrupts at level 6 must be rescheduleable to *any* IPL.  In
+       order to not be intrusive on existing ISA code a scheme
+       inspired by Markus Wild's LEV6_DEFER were designed by Niklas
+       Hallqvist <niklas@appli.se>.  Every Amiga-native driver for
+       devices at IPL 6 need to register a mapped IPL at which it
+       wants its interrupts to be serviced.  At interrupt time the
+       level 6 interrupts get blocked just like in LEV6_DEFER, and
+       then the system will loop through the interrupt levels from
+       high to low IPL servicing the highest interrupt scheduled.
+       There is special care taken to interrupts coming in while
+       already at some IPL above zero.
+ 
+ 4     IPL_REMAP_2
+ 
+       This system isn't yet ready, there are only hooks for it yet.
+       It is an experiment meant to address the performance problems
+       of IPL_REMAP_1 and ISA-drivers needing fast handling, like
+       fast serial devices.
Index: src/sys/arch/amiga/amiga/amiga_init.c
diff -c src/sys/arch/amiga/amiga/amiga_init.c:1.3 src/sys/arch/amiga/amiga/amiga_init.c:1.4
*** src/sys/arch/amiga/amiga/amiga_init.c:1.3   Tue Nov 28 12:35:58 1995
--- src/sys/arch/amiga/amiga/amiga_init.c       Tue Feb  6 02:16:29 1996
***************
*** 82,92 ****
   */
  vm_offset_t INTREQRaddr;
  vm_offset_t INTREQWaddr;
! 
! /*
!  * these are used by the extended spl?() macros.
!  */
! volatile unsigned short *amiga_intena_read, *amiga_intena_write;
  
  /*
   * the number of pages in our hw mapping and the start address
--- 82,89 ----
   */
  vm_offset_t INTREQRaddr;
  vm_offset_t INTREQWaddr;
! vm_offset_t INTENARaddr;
! vm_offset_t INTENAWaddr;
  
  /*
   * the number of pages in our hw mapping and the start address
***************
*** 596,601 ****
--- 593,600 ----
        CUSTOMbase = CUSTOMADDR;
        INTREQRaddr = (vm_offset_t)&custom.intreqr;
        INTREQWaddr = (vm_offset_t)&custom.intreq;
+       INTENARaddr = (vm_offset_t)&custom.intenar;
+       INTENAWaddr = (vm_offset_t)&custom.intena;
  
        /*
         * Get our chip memory allocation system working
***************
*** 620,632 ****
        custom.intreq = 0x7fff;                 /* clear any current */
        ciaa.icr = 0x7f;                        /* and keyboard */
        ciab.icr = 0x7f;                        /* and again */
- 
-       /*
-        * remember address of read and write intena register for use
-        * by extended spl?() macros.
-        */
-       amiga_intena_read  = &custom.intenar;
-       amiga_intena_write = &custom.intena;
  
        /*
         * This is needed for 3000's with superkick ROM's. Bit 7 of
--- 619,624 ----
Index: src/sys/arch/amiga/amiga/genassym.c
diff -c src/sys/arch/amiga/amiga/genassym.c:1.1.1.1 src/sys/arch/amiga/amiga/genassym.c:1.2
*** src/sys/arch/amiga/amiga/genassym.c:1.1.1.1 Wed Oct 18 02:49:52 1995
--- src/sys/arch/amiga/amiga/genassym.c Tue Feb  6 02:16:30 1996
***************
*** 110,115 ****
--- 110,116 ----
        printf("#define\tT_TRAP15 %d\n", T_TRAP15);
        printf("#define\tPSL_S %d\n", PSL_S);
        printf("#define\tPSL_IPL7 %d\n", PSL_IPL7);
+       printf("#define\tPSL_IPL %d\n", PSL_IPL);
        printf("#define\tPSL_LOWIPL %d\n", PSL_LOWIPL);
        printf("#define\tPSL_HIGHIPL %d\n", PSL_HIGHIPL);
        printf("#define\tPSL_USER %d\n", PSL_USER);
Index: src/sys/arch/amiga/amiga/isr.h
diff -c src/sys/arch/amiga/amiga/isr.h:1.1.1.1 src/sys/arch/amiga/amiga/isr.h:1.2
*** src/sys/arch/amiga/amiga/isr.h:1.1.1.1      Wed Oct 18 02:49:52 1995
--- src/sys/arch/amiga/amiga/isr.h      Tue Feb  6 02:16:31 1996
***************
*** 41,46 ****
--- 41,53 ----
        int     (*isr_intr)();
        void    *isr_arg;
        int     isr_ipl;
+ #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+       int     isr_mapped_ipl;
+ #ifdef IPL_REMAP_2
+       void    (*isr_ackintr)();
+       int     isr_status;
+ #endif
+ #endif
  };
  
  #define       NISR            3
***************
*** 53,56 ****
--- 60,69 ----
  void alloc_sicallback __P((void));
  void add_sicallback __P((sifunc_t, void *, void *));
  void rem_sicallback __P((sifunc_t));
+ #endif
+ 
+ #ifdef IPL_REMAP2
+ #define ISR_IDLE      0
+ #define ISR_WAITING   1
+ #define ISR_BUSY      2
  #endif
Index: src/sys/arch/amiga/amiga/locore.s
diff -c src/sys/arch/amiga/amiga/locore.s:1.3 src/sys/arch/amiga/amiga/locore.s:1.4
*** src/sys/arch/amiga/amiga/locore.s:1.3       Thu Dec 14 18:57:48 1995
--- src/sys/arch/amiga/amiga/locore.s   Tue Feb  6 02:16:31 1996
***************
*** 43,49 ****
   *
   * Original (hp300) Author: unknown, maybe Mike Hibler?
   * Amiga author: Markus Wild
!  * Other contributors: Bryan Ford (kernel reload stuff)
   */
  
  #include "assym.s"
--- 43,50 ----
   *
   * Original (hp300) Author: unknown, maybe Mike Hibler?
   * Amiga author: Markus Wild
!  * Other contributors: Bryan Ford (kernel reload stuff),
!  *                   Niklas Hallqvist (remapping interrupt system)
   */
  
  #include "assym.s"
***************
*** 53,66 ****
  
  #include <amiga/amiga/vectors.s>
  #include <amiga/amiga/custom.h>
! 
  #define CIAAADDR(ar)  movl    _CIAAbase,ar
  #define CIABADDR(ar)  movl    _CIABbase,ar
  #define CUSTOMADDR(ar)        movl    _CUSTOMbase,ar
  #define INTREQRADDR(ar)       movl    _INTREQRaddr,ar
  #define INTREQWADDR(ar)       movl    _INTREQWaddr,ar
! #define INTENAWADDR(ar) movl  _amiga_intena_write,ar
! #define       INTENARADDR(ar) movl    _amiga_intena_read,ar
  
        .text
  /*
--- 54,68 ----
  
  #include <amiga/amiga/vectors.s>
  #include <amiga/amiga/custom.h>
! #include "ser.h"
!       
  #define CIAAADDR(ar)  movl    _CIAAbase,ar
  #define CIABADDR(ar)  movl    _CIABbase,ar
  #define CUSTOMADDR(ar)        movl    _CUSTOMbase,ar
  #define INTREQRADDR(ar)       movl    _INTREQRaddr,ar
  #define INTREQWADDR(ar)       movl    _INTREQWaddr,ar
! #define INTENAWADDR(ar) movl  _INTENAWaddr,ar
! #define       INTENARADDR(ar) movl    _INTENARaddr,ar
  
        .text
  /*
***************
*** 477,488 ****
   * Interrupt handlers.
   *
   *    Level 0:        Spurious: ignored.
!  *    Level 1:        builtin-RS232 TBE, softint (not used yet)
!  *    Level 2:        keyboard (CIA-A) + DMA + SCSI
   *    Level 3:        VBL
!  *    Level 4:        not used
   *    Level 5:        builtin-RS232 RBF
!  *    Level 6:        Clock (CIA-B-Timers)
   *    Level 7:        Non-maskable: shouldn't be possible. ignore.
   */
  
--- 479,490 ----
   * Interrupt handlers.
   *
   *    Level 0:        Spurious: ignored.
!  *    Level 1:        builtin-RS232 TBE, softint
!  *    Level 2:        keyboard (CIA-A) + DMA + SCSI + External devices
   *    Level 3:        VBL
!  *    Level 4:        audio (and deferred IPL 6 when LEV6_DEFER)
   *    Level 5:        builtin-RS232 RBF
!  *    Level 6:        Clock (CIA-B-Timers) + External devices
   *    Level 7:        Non-maskable: shouldn't be possible. ignore.
   */
  
***************
*** 490,496 ****
   * and serial RBF (int5) specially, to improve performance
   */
  
!       .globl  _intrhand, _hardclock
  
  _spurintr:
        addql   #1,_intrcnt+0
--- 492,499 ----
   * and serial RBF (int5) specially, to improve performance
   */
  
!       .globl  _intrhand
!       .globl  _hardclock
  
  _spurintr:
        addql   #1,_intrcnt+0
***************
*** 499,505 ****
  
  _lev5intr:
        moveml  d0/d1/a0/a1,sp@-
- #include "ser.h"
  #if NSER > 0
        jsr     _ser_fastint
  #else
--- 502,507 ----
***************
*** 517,523 ****
  #ifndef LEV6_DEFER
  _lev4intr:
  #endif
!       moveml  #0xC0C0,sp@-
  Lintrcommon:
        lea     _intrcnt,a0
        movw    sp@(22),d0              | use vector offset
--- 519,525 ----
  #ifndef LEV6_DEFER
  _lev4intr:
  #endif
!       moveml  d0-d1/a0-a1,sp@-
  Lintrcommon:
        lea     _intrcnt,a0
        movw    sp@(22),d0              | use vector offset
***************
*** 527,544 ****
        clrw    sp@-                    |    padded to longword
        jbsr    _intrhand               | handle interrupt
        addql   #4,sp                   | pop SR
!       moveml  sp@+,#0x0303
        addql   #1,_cnt+V_INTR
        jra     rei
  
  _lev6intr:
  #ifdef LEV6_DEFER
        /*
         * cause a level 4 interrupt (AUD3) to occur as soon
         * as we return. Block generation of level 6 ints until
         * we have dealt with this one.
         */
!       moveml  #0x8080,sp@-
        INTREQRADDR(a0)
        movew   a0@,d0
        btst    #INTB_EXTER,d0
--- 529,559 ----
        clrw    sp@-                    |    padded to longword
        jbsr    _intrhand               | handle interrupt
        addql   #4,sp                   | pop SR
!       moveml  sp@+,d0-d1/a0-a1
        addql   #1,_cnt+V_INTR
        jra     rei
  
+ | Both IPL_REMAP_1 and IPL_REMAP_2 are experimental interruptsystems from
+ | Niklas Hallqvist <niklas@appli.se>, checkout amiga/amiga/README.ints for
+ | details...
+ #ifdef IPL_REMAP_1
+       .globl  _isr_exter_ipl
+       .globl  _isr_exter_highipl
+       .globl  _isr_exter_lowipl
+ #endif
+ #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+       .globl  _hardclock_frame
+ #endif
+       
  _lev6intr:
+ #ifndef IPL_REMAP_1
  #ifdef LEV6_DEFER
        /*
         * cause a level 4 interrupt (AUD3) to occur as soon
         * as we return. Block generation of level 6 ints until
         * we have dealt with this one.
         */
!       moveml  d0/a0,sp@-
        INTREQRADDR(a0)
        movew   a0@,d0
        btst    #INTB_EXTER,d0
***************
*** 548,564 ****
        INTENAWADDR(a0)
        movew   #INTF_EXTER,a0@
        movew   #INTF_SETCLR+INTF_AUD3,a0@      | make sure THIS one is ok...
!       moveml  sp@+,#0x0101
        rte
  Llev6spur:
        addql   #1,_intrcnt+36          | count spurious level 6 interrupts
!       moveml  sp@+,#0x0101
        rte
  
  _lev4intr:
  _fake_lev6intr:
  #endif
!       moveml  #0xC0C0,sp@-
  #ifdef LEV6_DEFER
        /*
         * check for fake level 6
--- 563,579 ----
        INTENAWADDR(a0)
        movew   #INTF_EXTER,a0@
        movew   #INTF_SETCLR+INTF_AUD3,a0@      | make sure THIS one is ok...
!       moveml  sp@+,d0/a0
        rte
  Llev6spur:
        addql   #1,_intrcnt+36          | count spurious level 6 interrupts
!       moveml  sp@+,d0/a0
        rte
  
  _lev4intr:
  _fake_lev6intr:
  #endif
!       moveml  d0-d1/a0-a1,sp@-
  #ifdef LEV6_DEFER
        /*
         * check for fake level 6
***************
*** 592,598 ****
  Lskipciab:
  | process any other CIAB interrupts?
  Llev6done:
!       moveml  sp@+,#0x0303            | restore scratch regs
        addql   #1,_cnt+V_INTR          | chalk up another interrupt
        jra     rei                     | all done [can we do rte here?]
  Lchkexter:
--- 607,613 ----
  Lskipciab:
  | process any other CIAB interrupts?
  Llev6done:
!       moveml  sp@+,d0-d1/a0-a1        | restore scratch regs
        addql   #1,_cnt+V_INTR          | chalk up another interrupt
        jra     rei                     | all done [can we do rte here?]
  Lchkexter:
***************
*** 622,627 ****
--- 637,671 ----
        addql   #1,_intrcnt+24          | count EXTER interrupts
        jra     Llev6done
  
+ #else /* IPL_REMAP_1 */
+ 
+       moveml  d0-d1/a0-a1,sp@-        | save clobbered regs
+ #if 0
+       INTREQRADDR(a0)
+       movew   a0@,d0
+       btst    #INTB_EXTER,d0          | check for non-EXTER INT6 ints
+       jne     Lexter
+       | register spurious int6 interrupt
+ Lexter:       
+ #endif
+       moveal  #_hardclock_frame,a0    | store the clockframe
+       movel   sp@(16),a0@+            | where hardclock will find it
+       movel   sp@(20),a0@
+       INTENAWADDR(a0)
+       movew   #INTF_EXTER,a0@         | disable EXTER ints
+       movew   sp@(16),d0              | get PS-word
+       andl    #PSL_IPL,d0             | only IPL is interesting
+       orw     #PSL_S,d0               | note we're in kernel mode
+       movel   d0,sp@-
+       movel   _isr_exter_highipl,sp@- | start out at the highest IPL
+       jbsr    _walk_ipls              | run all ISRs at appropriate IPLs
+       addql   #8,sp
+       addql   #1,_intrcnt+24          | add another exter interrupt
+       moveml  sp@+,d0-d1/a0-a1        | restore scratch regs
+       addql   #1,_cnt+V_INTR          | chalk up another interrupt
+       jra     Lastchk                 | all done [can we do rte here?]
+ #endif
+       
  _lev7intr:
        addql   #1,_intrcnt+28
        /*
***************
*** 631,637 ****
         */
        rte                             | all done
  
- 
  /*
   * Emulation of VAX REI instruction.
   *
--- 675,680 ----
***************
*** 657,662 ****
--- 700,719 ----
        tstl    _panicstr               | have we paniced?
        jne     Ldorte                  | yes, do not make matters worse
  #endif
+ #ifdef IPL_REMAP_1
+       tstl    _isr_exter_ipl          | IPL lowering in process?
+       jeq     Lastchk                 | no, go on to check for ASTs
+       moveml  d0-d1/a0-a1,sp@-        | save scratch regs
+       movw    sp@(16),d0              | get PS
+       andl    #PSL_IPL,d0             | we're only interested in the IPL
+       orw     #PSL_S,d0               | note that we're in kernel mode
+       movel   d0,sp@-
+       movel   _isr_exter_ipl,sp@-     | start where we left last walk_ipls
+       jbsr    _walk_ipls              | run needed ISRs
+       addql   #8,sp                   | pop params
+       moveml  sp@+,d0-d1/a0-a1        | restore scratch regs
+ Lastchk:      
+ #endif
        tstl    _astpending             | AST pending?
        jeq     Ldorte                  | no, done
  Lrei1:
***************
*** 1254,1260 ****
        pflusha                         | flush entire TLB
        jra     Lres3
  Lres2:
!       .word   0xf518          | pflusha (68040)
        movl    #CACHE40_ON,d0
        movc    d0,cacr                 | invalidate cache(s)
  Lres3:
--- 1311,1317 ----
        pflusha                         | flush entire TLB
        jra     Lres3
  Lres2:
!       .word   0xf518                  | pflusha (68040)
        movl    #CACHE40_ON,d0
        movc    d0,cacr                 | invalidate cache(s)
  Lres3:
***************
*** 1408,1414 ****
  Lmc68851a:
        rts
  Ltbia040:
!       .word   0xf518          | pflusha
        rts
  
  /*
--- 1465,1471 ----
  Lmc68851a:
        rts
  Ltbia040:
!       .word   0xf518                  | pflusha
        rts
  
  /*
***************
*** 1434,1443 ****
  Ltbis040:
        moveq   #FC_SUPERD,d0           | select supervisor
        movc    d0,dfc
!       .word   0xf508          | pflush a0@
        moveq   #FC_USERD,d0            | select user
        movc    d0,dfc
!       .word   0xf508          | pflush a0@
        rts
  
  /*
--- 1491,1500 ----
  Ltbis040:
        moveq   #FC_SUPERD,d0           | select supervisor
        movc    d0,dfc
!       .word   0xf508                  | pflush a0@
        moveq   #FC_USERD,d0            | select user
        movc    d0,dfc
!       .word   0xf508                  | pflush a0@
        rts
  
  /*
***************
*** 1461,1467 ****
        rts
  Ltbias040:
  | 68040 can't specify supervisor/user on pflusha, so we flush all
!       .word   0xf518          | pflusha
        rts
  
  /*
--- 1518,1524 ----
        rts
  Ltbias040:
  | 68040 can't specify supervisor/user on pflusha, so we flush all
!       .word   0xf518                  | pflusha
        rts
  
  /*
***************
*** 1485,1491 ****
        rts
  Ltbiau040:
  | 68040 can't specify supervisor/user on pflusha, so we flush all
!       .word   0xf518          | pflusha
        rts
  
  /*
--- 1542,1548 ----
        rts
  Ltbiau040:
  | 68040 can't specify supervisor/user on pflusha, so we flush all
!       .word   0xf518                  | pflusha
        rts
  
  /*
***************
*** 1680,1686 ****
        cmpl    #MMU_68040,_mmutype
        jeq     Lploadw040
        ploadw  #1,a0@                  | pre-load translation
! Lploadw040:                   | should 68040 do a ptest?
        rts
  
  ENTRY(_insque)
--- 1737,1743 ----
        cmpl    #MMU_68040,_mmutype
        jeq     Lploadw040
        ploadw  #1,a0@                  | pre-load translation
! Lploadw040:                           | should 68040 do a ptest?
        rts
  
  ENTRY(_insque)
Index: src/sys/arch/amiga/amiga/machdep.c
diff -c src/sys/arch/amiga/amiga/machdep.c:1.4 src/sys/arch/amiga/amiga/machdep.c:1.5
*** src/sys/arch/amiga/amiga/machdep.c:1.4      Fri Jan  5 09:17:38 1996
--- src/sys/arch/amiga/amiga/machdep.c  Tue Feb  6 02:16:33 1996
***************
*** 142,148 ****
  /* the following is used externally (sysctl_hw) */
  char machine[] = "amiga";
   
!  /*
   * Console initialization: called early on from main,
   * before vm init or startup.  Do enough configuration
   * to choose and initialize a console.
--- 142,229 ----
  /* the following is used externally (sysctl_hw) */
  char machine[] = "amiga";
   
! struct isr *isr_ports;
! #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
! struct isr *isr_exter[7];
! #else
! struct isr *isr_exter;
! #endif
! 
! #ifdef IPL_REMAP_1
! int isr_exter_lowipl = 7;
! int isr_exter_highipl = 0;
! int isr_exter_ipl = 0;
! 
! /*
!  * Poll all registered ISRs starting at IPL start_ipl going down to
!  * isr_exter_lowipl.  If we reach the IPL of ending_psw along the way
!  * just return stating in isr_exter_ipl that we need to run the remaining
!  * layers later when the IPL gets lowered (i.e. a spl? call).  If some
!  * ISR handles the interrupt, or all layers have been processed, enable
!  * EXTER interrupts again and return.
!  */
! void
! walk_ipls (start_ipl, ending_psw)
!       int start_ipl;
!       int ending_psw;
! {
!       int i;
!       int handled = 0;
! 
!       for (i = start_ipl; !handled && i >= isr_exter_lowipl; i--) {
!               register int psw = i << 8 | PSL_S;
!               struct isr *isr;
!                     
!               if (psw <= ending_psw) {
!                       isr_exter_ipl = i;
!                       return;
!               }
!               __asm __volatile("movew %0,sr" : : "d" (psw) : "cc");
!               for (isr = isr_exter[i]; !handled && isr; isr = isr->isr_forw)
!                       handled = (*isr->isr_intr)(isr->isr_arg);
!       }
!       isr_exter_ipl = 0;
!       __asm __volatile("movew %0,sr" : : "di" (PSL_S|PSL_IPL6) : "cc");
!       custom.intreq = INTF_EXTER;
!       custom.intena = INTF_SETCLR | INTF_EXTER;
! }
! #endif
! 
! #ifdef IPL_REMAP_2
! /*
!  * Service all waiting ISRs starting from current IPL to npsl.
!  */
! void
! walk_ipls (npsl)
!       int npsl;
! {
!         struct isr *isr_head;
!       register struct isr *isr;
!       int opsl;
!       register int psl;
! 
!       psl = opsl = spl7();
!       isr_head = &isr_exter[(psl & PSL_IPL) >> 8];
! redo_ipl:
!       while (psl > to_psl) {
!               for (isr = isr_head; isr; isr = isr->isr_forw) {
!                       if (isr->isr_status == ISR_WAIT) {
!                               splx(psl);
!                               isr->isr_status = ISR_BUSY;
!                               (*isr->isr_intr)(isr->isr_arg);
!                               isr->isr_status = ISR_IDLE;
!                               spl7();
!                               goto redo_ipl;
!                       }
!               }
!               psl -= PSL_IPL1;
!               isr_head--;
!       }
!       return opsl;
! }
! #endif
! 
! /*
   * Console initialization: called early on from main,
   * before vm init or startup.  Do enough configuration
   * to choose and initialize a console.
***************
*** 1143,1159 ****
   * function calls executed at very low interrupt priority.
   * Example for use is keyboard repeat, where the repeat 
   * handler running at splclock() triggers such a (hardware
!  * aided) software interrupt.
!  * Note: the installed functions are currently called in a
!  * LIFO fashion, might want to change this to FIFO
!  * later.
   */
  struct si_callback {
        struct si_callback *next;
        void (*function) __P((void *rock1, void *rock2));
        void *rock1, *rock2;
  };
  static struct si_callback *si_callbacks;
  static struct si_callback *si_free;
  #ifdef DIAGNOSTIC
  static int ncb;               /* number of callback blocks allocated */
--- 1224,1240 ----
   * function calls executed at very low interrupt priority.
   * Example for use is keyboard repeat, where the repeat 
   * handler running at splclock() triggers such a (hardware
!  * aided) software interrupt.  These functions are called in
!  * a FIFO manner as expected.
   */
+ 
  struct si_callback {
        struct si_callback *next;
        void (*function) __P((void *rock1, void *rock2));
        void *rock1, *rock2;
  };
  static struct si_callback *si_callbacks;
+ static struct si_callback *si_callbacks_end;
  static struct si_callback *si_free;
  #ifdef DIAGNOSTIC
  static int ncb;               /* number of callback blocks allocated */
***************
*** 1212,1219 ****
        si->rock2 = rock2;
  
        s = splhigh();
!       si->next = si_callbacks;
!       si_callbacks = si;
        splx(s);
  
        /*
--- 1293,1304 ----
        si->rock2 = rock2;
  
        s = splhigh();
!       si->next = NULL;
!       if (si_callbacks)
!               si_callbacks_end->next = si;
!       else
!               si_callbacks = si;
!       si_callbacks_end = si;
        splx(s);
  
        /*
***************
*** 1245,1250 ****
--- 1330,1337 ----
                                psi->next = nsi;
                        else
                                si_callbacks = nsi;
+                       if (si == si_callbacks_end)
+                               si_callbacks_end = psi;
                }
                si = nsi;
        }
***************
*** 1262,1267 ****
--- 1349,1355 ----
  
        do {
                s = splhigh ();
+               /* Yes, that's an *assignment* below!  */
                if (si = si_callbacks)
                        si_callbacks = si->next;
                splx(s);
***************
*** 1289,1311 ****
  #endif
  }
  
- struct isr *isr_ports;
- struct isr *isr_exter;
- 
  void
  add_isr(isr)
        struct isr *isr;
  {
        struct isr **p, *q;
  
!       p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter;
        while ((q = *p) != NULL)
                p = &q->isr_forw;
        isr->isr_forw = NULL;
        *p = isr;
        /* enable interrupt */
!       custom.intena = isr->isr_ipl == 2 ? INTF_SETCLR | INTF_PORTS :
!           INTF_SETCLR | INTF_EXTER;
  }
  
  void
--- 1377,1406 ----
  #endif
  }
  
  void
  add_isr(isr)
        struct isr *isr;
  {
        struct isr **p, *q;
  
! #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
!       p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter[isr->isr_mapped_ipl];
!       if (isr->isr_ipl == 6) {
!               if (isr->isr_mapped_ipl > isr_exter_highipl)
!                       isr_exter_highipl = isr->isr_mapped_ipl;
!               if (isr->isr_mapped_ipl < isr_exter_lowipl)
!                       isr_exter_lowipl = isr->isr_mapped_ipl;
!       }
! #else
!       p = isr->isr_ipl == 2 ? &isr_ports : &isr_exter;
! #endif
        while ((q = *p) != NULL)
                p = &q->isr_forw;
        isr->isr_forw = NULL;
        *p = isr;
        /* enable interrupt */
!       custom.intena = INTF_SETCLR |
!           (isr->isr_ipl == 2 ? INTF_PORTS : INTF_EXTER);
  }
  
  void
***************
*** 1314,1320 ****
--- 1409,1419 ----
  {
        struct isr **p, *q;
  
+ #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+       p = isr->isr_ipl == 6 ? &isr_exter[isr->isr_mapped_ipl] : &isr_ports;
+ #else
        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
+ #endif
        while ((q = *p) != NULL && q != isr)
                p = &q->isr_forw;
        if (q)
***************
*** 1322,1330 ****
--- 1421,1448 ----
        else
                panic("remove_isr: handler not registered");
        /* disable interrupt if no more handlers */
+ #if defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
+       p = isr->isr_ipl == 6 ? &isr_exter[isr->isr_mapped_ipl] : &isr_ports;
+       if (*p == NULL) {
+               if (isr->isr_ipl == 6) {
+                       if (isr->isr_mapped_ipl == isr_exter_lowipl)
+                               while (isr_exter_lowipl++ < 6 &&
+                                   !isr_exter[isr_exter_lowipl])
+                                       ;
+                       if (isr->isr_mapped_ipl == isr_exter_highipl)
+                               while (isr_exter_highipl-- > 0 &&
+                                   !isr_exter[isr_exter_highipl])
+                                       ;
+                       if (isr_exter_lowipl == 7)
+                               custom.intena = INTF_EXTER;
+               } else if (isr->isr_ipl == 2)
+                       custom.intena = INTF_PORTS;
+       }
+ #else
        p = isr->isr_ipl == 6 ? &isr_exter : &isr_ports;
        if (*p == NULL)
                custom.intena = isr->isr_ipl == 6 ? INTF_EXTER : INTF_PORTS;
+ #endif
  }
  
  intrhand(sr)
***************
*** 1357,1363 ****
                        /*
                         * first clear the softint-bit
                         * then process all classes of softints.
!                        * this order is dicated by the nature of 
                         * software interrupts.  The other order
                         * allows software interrupts to be missed
                         */
--- 1475,1481 ----
                        /*
                         * first clear the softint-bit
                         * then process all classes of softints.
!                        * this order is dictated by the nature of 
                         * software interrupts.  The other order
                         * allows software interrupts to be missed
                         */
***************
*** 1394,1404 ****
                break;
      case 3: 
        /* VBL */
!               if (ireq & INTF_BLIT)  
                        blitter_handler();
!               if (ireq & INTF_COPER)  
                        copper_handler();
!               if (ireq & INTF_VERTB) 
                        vbl_handler();
                break;
  #if 0
--- 1512,1522 ----
                break;
      case 3: 
        /* VBL */
!               if (ireq & INTF_BLIT)
                        blitter_handler();
!               if (ireq & INTF_COPER)
                        copper_handler();
!               if (ireq & INTF_VERTB)
                        vbl_handler();
                break;
  #if 0
***************
*** 1487,1493 ****
  
        if (doingdump)
                return;
!       s = splhigh();
        doingdump = 1;
        printf("pid = %d, pc = %s, ", curproc->p_pid, hexstr(fp->f_pc, 8));
        printf("ps = %s, ", hexstr(fp->f_sr, 4));
--- 1605,1611 ----
  
        if (doingdump)
                return;
!       s = spl7();
        doingdump = 1;
        printf("pid = %d, pc = %s, ", curproc->p_pid, hexstr(fp->f_pc, 8));
        printf("ps = %s, ", hexstr(fp->f_sr, 4));
Index: src/sys/arch/amiga/conf/FILIPPA
*** /dev/null     Tue Feb  6 11:40:53 1996
--- src/sys/arch/amiga/conf/FILIPPA     Tue Feb  6 09:32:42 1996
***************
*** 0 ****
--- 1,218 ----
+ #     $Id: FILIPPA,v 1.1 1996/02/06 09:17:41 niklas Exp $
+ 
+ #
+ # GENERIC AMIGA
+ #
+ # This configuration file contains all possible options
+ #
+ 
+ include "std.amiga"
+ 
+ maxusers      8
+ options               TIMEZONE=300, DST=1
+ 
+ #
+ # processors this kernel should support
+ #
+ options               "M68040"        # support for 040
+ options               FPSP            # MC68040 floating point support
+ #options              "M68030"        # support for 030
+ #options              "M68020"        # support for 020/851
+ options               FPCOPROC        # Support for MC6888[12] (Required)
+ 
+ options               SWAPPAGER       # Pager for processes (Required)
+ options               VNODEPAGER      # Pager for vnodes (Required)
+ options               DEVPAGER        # Pager for devices (Required)
+ 
+ #
+ # Networking options
+ #
+ options               INET            # IP networking support (Required)
+ #options      ISO             # ISO Networking support
+ #options      TPIP            # ARGO TP networking support
+ #options      CCITT           # CCITT X.25
+ #options      NS              # Xerox XNS
+ #options      EON             # ISO CLNL over IP
+ options       GATEWAY         # Packet forwarding
+ #options      DIRECTED_BROADCAST      # Broadcast across subnets
+ #options      NSIP            # XNS over IP
+ 
+ #
+ # File system related options
+ #
+ #options              QUOTA           # Disk quotas for local disks
+ options               NFSSERVER       # Network File System server side code
+ options               NFSCLIENT       # Network File System client side code
+ 
+ #
+ # File systems
+ #
+ options               FFS             # Berkeley fast file system
+ options               MFS             # Memory based filesystem
+ options               PROCFS          # Process filesystem
+ options               KERNFS          # Kernel parameter filesystem (Recommended)
+ options               FDESC           # /dev/fd filesystem
+ options               NULLFS          # Loopback filesystem
+ options               FIFO            # FIFO operations on vnodes (Recommended)
+ options               ADOSFS          # AmigaDOS file system
+ options               "CD9660"        # ISO 9660 file system, with Rock Ridge
+ options               UNION           # union file system
+ #options              UMAPFS          # uid/gid remapping filesystem
+ #options      PORTAL          # Portal filesystem
+ #options      MSDOSFS         # MS-DOS filesystem
+ 
+ 
+ #
+ # Compatability options for various existing systems
+ #
+ options               "COMPAT_10"     # compatability with older NetBSD release
+ options               "COMPAT_09"     # compatability with older NetBSD release
+ options               "COMPAT_43"     # 4.3 BSD compatible system calls
+ options               COMPAT_SUNOS    # Support to run Sun (m68k) executables
+ options               "TCP_COMPAT_42" # Use 4.2 BSD style TCP
+ options               "COMPAT_NOMID"  # allow nonvalid machine id executables
+ #options      COMPAT_HPUX     # HP300 compatability
+ 
+ #
+ # Support for System V IPC facilities.
+ #
+ options               SYSVSHM         # System V-like shared memory
+ options               SYSVMSG         # System V-like messages
+ options               SYSVSEM         # System V-like semaphores
+ 
+ #
+ # Support for various kernel options
+ #
+ #options              GENERIC         # Mini-root boot support
+ options               LKM             # Loadable kernel modules
+ options               KTRACE          # Add kernel tracing system call
+ options               DIAGNOSTIC      # Add additional error checking code
+ options               "NKMEMCLUSTERS=256"     # Size of kernel malloc area
+ 
+ #
+ # Misc. debuging options
+ #
+ options               PANICWAIT       # Require keystroke to dump/reboot
+ options       DEBUG           # Add debugging statements
+ options               DDB             # Kernel debugger
+ #options      SYSCALL_DEBUG   # debug all syscalls.
+ #options      SCSIDEBUG       # Add SCSI debugging statements
+ #options      KGDB            # Kernel debugger (KGDB) support
+ #options      PANICBUTTON     # Forced crash via keypress (???)
+ 
+ #
+ # Amiga specific options
+ #
+ options               MACHINE_NONCONTIG # Non-contiguous memory support
+ 
+ options               RETINACONSOLE   # enable code to allow retina to be console
+ #options              ULOWELLCONSOLE  # enable code to allow a2410 to be console
+ #options         CL5426CONSOLE   # Cirrus console
+ 
+ #options              GRF_ECS         # Enhanced Chip Set
+ #options              GRF_NTSC        # NTSC
+ options               GRF_PAL         # PAL
+ #options              "GRF_A2024"     # Support for the A2024
+ #options              GRF_AGA         # AGA Chip Set
+ #options              GRF_CL5426      # Cirrus board support
+ #options      "KFONT_8X11"    # 8x11 font
+ #options              LEV6_DEFER      # Defer handling of level 6 interrupts
+ options               IPL_REMAP_1     # Remap level 6 ints version 1
+ #options              IPL_REMAP_2     # Remap level 6 ints version 2
+ 
+ # This is how you would tell the kernel the A2410 oscillator frequencies:
+ # The used frequencies are the defaults, and don't need option setting
+ #options      "ULOWELL_OSC1=36000000"
+ #options      "ULOWELL_OSC2=66667000"
+ 
+ # This is how you specify the blitting speed, higher values may speed up blits
+ # a littel bit.  If you raise this value too much some trash may appear.
+ # the commented version is the default.
+ #options      RH_MEMCLK 61000000
+ # this option enables the 64 bit sprite which doesn't seems to be work
+ # for quite a few people.  E.g. The cursor sprite will turn to a block
+ # when moved to the top of the screen in X.
+ #options      RH_64BIT_SPRITE
+ # enables fast scroll code appears to now work on 040 systems.
+ #options      RETINA_SPEED_HACK
+ 
+ grfcc0                at mainbus0             # custom chips
+ grfrt0                at zbus0                # retina II
+ #grfrh0               at zbus0                # retina III
+ #grfcl*               at zbus0                # Picasso II/Piccalo/Spectrum
+ #grful0               at zbus0                # A2410
+ #grfcv0               at zbus0                # CyverVision 64
+ 
+ grf0          at grfcc0
+ grf1          at grfrt0
+ #grf2         at grfrh0
+ #grf3         at grfcl?
+ #grf4         at grful0
+ #grf5         at grfcv0
+ 
+ ite0          at grf0                 # terminal emulators for grf's
+ ite1          at grf1                 # terminal emulators for grf's
+ #ite2         at grf2                 # terminal emulators for grf's
+ #ite3         at grf3                 # terminal emulators for grf's
+ #ite4         at grf4                 # terminal emulators for grf's
+ 
+ #msc0         at zbus0                # A2232 MSC multiport serial.
+ #mfc0         at zbus0                # MultiFaceCard I/O board
+ #mfcs0                at mfc0 unit 0          # MFC serial
+ #mfcs1                at mfc0 unit 1          # MFC serial
+ #mfcp0                at mfc0 unit 0          # MFC parallel [not available yet]
+ #mfc1         at zbus0                # MultiFaceCard 2nd I/O board
+ #mfcs2                at mfc1 unit 0
+ #mfcs3                at mfc1 unit 1
+ #mfcp1                at mfc1 unit 0
+ 
+ #le0          at zbus0                # Lance ethernet.
+ #ed0          at zbus0                # dp8390 ethernet
+ #es0          at zbus0                # SMC 91C90 ethernet
+ #qn0          at zbus0                # quicknet ethernet
+ #ae0          at zbus0                # Ariadne ethernet
+ #bah0         at zbus0                # C= arcnet
+ 
+ 
+ # scsi stuff, all possible
+ gvpbus*       at zbus0
+ gtsc0         at gvpbus?              # GVP series II scsi
+ #ahsc0                at mainbus0             # A3000 scsi
+ #atzsc0               at zbus0
+ #wstsc0               at zbus0                # Wordsync II scsi
+ #ivsc0                at zbus0                # IVS scsi
+ #mlhsc0               at zbus0                # Hacker scsi
+ #otgsc0               at zbus0                # 12 gauge scsi
+ zssc0         at zbus0                # Zeus scsi
+ #mgnsc0               at zbus0                # Magnum scsi
+ #wesc0                at zbus0                # Warp Engine scsi
+ #idesc0               at mainbus0             # A4000 & A1200 IDE
+ #afsc0                at zbus0                # A4091 scsi
+ #aftsc0               at mainbus0             # A4000T scsi
+ #flsc0                at zbus0                # FastlaneZ3 scsi
+ #bzsc0                at zbus0                # Blizzard 1230 scsi
+ 
+ scsibus0      at zssc0
+ 
+ # each hard drive from low target to high
+ # will configure to the next available sd unit number
+ sd0   at scsibus0 target 0 lun ?      # scsi disks
+ sd1   at scsibus0 target 3 lun ?      # scsi disks
+ #sd*  at scsibus? target ? lun ?      # scsi disks
+ 
+ st0   at scsibus0 target 5 lun ?      # scsi tapes
+ st*   at scsibus? target ? lun ?      # scsi tapes
+ cd0   at scsibus0 target 6 lun ?      # scsi cd's
+ cd*   at scsibus? target ? lun ?      # scsi cd's
+ 
+ pseudo-device sl                      # slip
+ pseudo-device ppp                     # ppp
+ pseudo-device view    10              # views
+ pseudo-device pty     16              # pseudo terminals
+ pseudo-device loop                    # network loopback
+ pseudo-device vnd     4
+ pseudo-device bpfilter        2       # berkeley packet filters
+ pseudo-device tun 2
+ 
+ config        bsd root on sd1a swap on sd1b dumps on sd1b
+ #config       bsd swap on generic
Index: src/sys/arch/amiga/conf/GENERIC
diff -c src/sys/arch/amiga/conf/GENERIC:1.4 src/sys/arch/amiga/conf/GENERIC:1.5
*** src/sys/arch/amiga/conf/GENERIC:1.4 Wed Jan 31 15:42:36 1996
--- src/sys/arch/amiga/conf/GENERIC     Tue Feb  6 02:17:42 1996
***************
*** 1,4 ****
! #     $Id: GENERIC,v 1.4 1996/01/31 22:42:36 niklas Exp $
  
  #
  # GENERIC AMIGA
--- 1,4 ----
! #     $Id: GENERIC,v 1.5 1996/02/06 09:17:42 niklas Exp $
  
  #
  # GENERIC AMIGA
***************
*** 116,121 ****
--- 116,124 ----
  options               GRF_AGA         # AGA Chip Set
  options               GRF_CL5426      # Cirrus board support
  #options      "KFONT_8X11"    # 8x11 font
+ #options              LEV6_DEFER      # Defer handling of level 6 interrupts
+ #options              IPL_REMAP_1     # Remap level 6 ints version 1
+ #options              IPL_REMAP_2     # Remap level 6 ints version 2
  
  # This is how you would tell the kernel the A2410 oscillator frequencies:
  # The used frequencies are the defaults, and don't need option setting
Index: src/sys/arch/amiga/dev/clock.c
diff -c src/sys/arch/amiga/dev/clock.c:1.1.1.1 src/sys/arch/amiga/dev/clock.c:1.2
*** src/sys/arch/amiga/dev/clock.c:1.1.1.1      Wed Oct 18 02:49:55 1995
--- src/sys/arch/amiga/dev/clock.c      Tue Feb  6 02:23:31 1996
***************
*** 50,55 ****
--- 50,56 ----
  #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,62 ****
--- 58,65 ----
  #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,69 ****
--- 67,81 ----
  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,145 ****
--- 149,174 ----
        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,159 ****
--- 179,195 ----
         */
        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,219 ****
  
        /*
         * set timer B in "count timer A underflows" mode
!        * set tiemr A in one-shot mode
         */
        ciaa.crb = (ciaa.crb & 0x80) | 0x48;
        ciaa.cra = (ciaa.cra & 0xc0) | 0x08;
--- 249,255 ----
  
        /*
         * set timer B in "count timer A underflows" mode
!        * set timer A in one-shot mode
         */
        ciaa.crb = (ciaa.crb & 0x80) | 0x48;
        ciaa.cra = (ciaa.cra & 0xc0) | 0x08;
Index: src/sys/arch/amiga/dev/mfc.c
diff -c src/sys/arch/amiga/dev/mfc.c:1.2 src/sys/arch/amiga/dev/mfc.c:1.3
*** src/sys/arch/amiga/dev/mfc.c:1.2    Wed Oct 25 19:04:42 1995
--- src/sys/arch/amiga/dev/mfc.c        Tue Feb  6 02:23:32 1996
***************
*** 362,367 ****
--- 362,370 ----
        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 */
Index: src/sys/arch/amiga/dev/mgnsc.c
diff -c src/sys/arch/amiga/dev/mgnsc.c:1.1.1.1 src/sys/arch/amiga/dev/mgnsc.c:1.2
*** src/sys/arch/amiga/dev/mgnsc.c:1.1.1.1      Wed Oct 18 02:50:00 1995
--- src/sys/arch/amiga/dev/mgnsc.c      Tue Feb  6 02:23:33 1996
***************
*** 129,134 ****
--- 129,138 ----
        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);
  
        /*
Index: src/sys/arch/amiga/dev/zssc.c
diff -c src/sys/arch/amiga/dev/zssc.c:1.1.1.1 src/sys/arch/amiga/dev/zssc.c:1.2
*** src/sys/arch/amiga/dev/zssc.c:1.1.1.1       Wed Oct 18 02:50:03 1995
--- src/sys/arch/amiga/dev/zssc.c       Tue Feb  6 02:23:34 1996
***************
*** 79,85 ****
        DV_DULL, sizeof(struct siop_softc), NULL, 0 };
  
  /*
!  * if we are an PPI Zeus
   */
  int
  zsscmatch(pdp, cdp, auxp)
--- 79,85 ----
        DV_DULL, sizeof(struct siop_softc), NULL, 0 };
  
  /*
!  * if we are a PPI Zeus
   */
  int
  zsscmatch(pdp, cdp, auxp)
***************
*** 130,135 ****
--- 130,139 ----
        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);
  
        /*
Index: src/sys/arch/amiga/include/param.h
diff -c src/sys/arch/amiga/include/param.h:1.2 src/sys/arch/amiga/include/param.h:1.3
*** src/sys/arch/amiga/include/param.h:1.2      Wed Jan 31 14:11:26 1996
--- src/sys/arch/amiga/include/param.h  Tue Feb  6 02:24:03 1996
***************
*** 147,232 ****
   */
  #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; \
! })
  #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
  #else
! #define _spl _spl_no_check
  #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()
  #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
  #define splclock()    spl4()
! #define splstatclock()        spl4()
! #define splvm()               spl4()
! #define splhigh()     spl4()
! #define splsched()    spl4()
  #endif
  
! #define splx(s)         _spl_no_check(s)
  
- #ifdef _KERNEL
  void delay __P((int));
  void DELAY __P((int));
  #endif
--- 147,249 ----
   */
  #include <machine/psl.h>
  
! #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
  
! #ifndef IPL_REMAP_2
! #define splx splraise
  #else
! 
! 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
  
! /*
!  * 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()
! #if defined(LEV6_DEFER) || defined(IPL_REMAP_1) || defined(IPL_REMAP_2)
  #define splclock()    spl4()
! #else
! #define splclock()    spl6()
  #endif
+ #define splstatclock()        splclock()
  
! /*
!  * 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)
  
  void delay __P((int));
  void DELAY __P((int));
  #endif
>Audit-Trail:
>Unformatted: