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: