diff --git a/rom/exec/addintserver.c b/rom/exec/addintserver.c index ae02732be9a..72b0612ad94 100644 --- a/rom/exec/addintserver.c +++ b/rom/exec/addintserver.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2017, The AROS Development Team. All rights reserved. + Copyright © 1995-2017, The AROS Development Team. All rights reserved. $Id$ Desc: Add interrupt client to chain of interrupt servers @@ -18,7 +18,7 @@ #include "chipset.h" #include "exec_locks.h" -static void krnIRQwrapper(void *data1, void *data2) +static void krnIRQwrapper(void *data1, void *data2) { struct Interrupt *irq = (struct Interrupt *)data1; struct ExecBase *SysBase = (struct ExecBase *)data2; @@ -63,18 +63,37 @@ static void krnIRQwrapper(void *data1, void *data2) ExecLog(SysBase, EXECDEBUGF_EXCEPTHANDLER, "AddIntServer: Int %d, Interrupt %p\n", intNumber, interrupt); + /* ------------------------------------------------------------ + * Kernel IRQs are NOT handled here. + * ------------------------------------------------------------ */ if (intNumber >= INTB_KERNEL) { /* N.B. ln_Succ is being re-purposed/abused here */ interrupt->is_Node.ln_Succ = KrnAddIRQHandler(intNumber - INTB_KERNEL, krnIRQwrapper, interrupt, SysBase); return; } - EXEC_LOCK_LIST_WRITE_AND_DISABLE(&SysBase->IntrList); + struct List *list = (struct List *)SysBase->IntVects[intNumber].iv_Data; + volatile UWORD *INTENA = (UWORD *)0xDFF09A; - Enqueue((struct List *)SysBase->IntVects[intNumber].iv_Data, &interrupt->is_Node); - CUSTOM_ENABLE(intNumber); - - EXEC_UNLOCK_LIST_AND_ENABLE(&SysBase->IntrList); + /* ------------------------------------------------------------ + * Disable() — classic Exec + * ------------------------------------------------------------ */ + Disable(); + + /* ------------------------------------------------------------ + * Insert interrupt server into vector list + * ------------------------------------------------------------ */ + Enqueue(list, &interrupt->is_Node); + + /* ------------------------------------------------------------ + * Enable the corresponding hardware interrupt + * ------------------------------------------------------------ */ + *INTENA = 0x8000 | (1 << intNumber); + + /* ------------------------------------------------------------ + * Enable() — classic Exec + * ------------------------------------------------------------ */ + Enable(); AROS_LIBFUNC_EXIT } /* AddIntServer */ diff --git a/rom/exec/disable.c b/rom/exec/disable.c index ea22576c631..ca2cd0593f4 100644 --- a/rom/exec/disable.c +++ b/rom/exec/disable.c @@ -1,6 +1,5 @@ /* - Copyright © 1995-2017, The AROS Development Team. All rights reserved. - $Id$ + Copyright © 1995-2017, The AROS Development Team. All rights reserved. Desc: Disable() - Stop interrupts from occurring. Lang: english @@ -29,12 +28,12 @@ /* FUNCTION This function will prevent interrupts from occuring (*). You can - start the interrupts again with a call to Enable(). + start the interrupts again with a call to Enable() Note that calls to Disable() nest, and for every call to Disable() you need a matching call to Enable(). - ***** WARNING ***** + ***** WARNING ***** Using this function is considered very harmful, and it should only ever be used to protect data that could also be accessed in interrupts. @@ -60,10 +59,10 @@ (*) On EXECSMP builds, Disable() only aplies to the processor it is called from (and needs to be re-enabled there also) Data which needs to be protected from parallel access will - also require a spinlock. + also require a spinlock. EXAMPLE - In most userspace code, you will not want to use this function. + In most userspace code, you will not want to use this function. BUGS The only architecture that you can rely on the registers being @@ -73,8 +72,6 @@ Forbid(), Permit(), Enable(), Wait() INTERNALS - This function must be replaced in the $(KERNEL) or $(ARCH) - directories in order to do some work. ******************************************************************************/ { @@ -84,12 +81,16 @@ D(bug("[Exec] Disable()\n");) - if (KernelBase) - KrnCli(); + /* + * - INTENA = $4000 (clear + disable all interrupts) + * - IDNestCnt++ + */ + volatile UWORD *INTENA = (UWORD *)0xDFF09A; - IDNESTCOUNT_INC; + *INTENA = 0x4000; + SysBase->IDNestCnt++; - D(bug("[Exec] Disable: IDNESTCOUNT = %d\n", IDNESTCOUNT_GET);) + D(bug("[Exec] Disable: IDNESTCOUNT = %d\n", SysBase->IDNestCnt);) AROS_LIBFUNC_EXIT } /* Disable() */ diff --git a/rom/exec/enable.c b/rom/exec/enable.c index ee7889a9b00..a8e6fdf442d 100644 --- a/rom/exec/enable.c +++ b/rom/exec/enable.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2018, The AROS Development Team. All rights reserved. + Copyright © 1995-2018, The AROS Development Team. All rights reserved. $Id$ Desc: Enable() - Allow interrupts to occur after Disable(). @@ -37,13 +37,12 @@ ***** WARNING ***** + It is quite possible to either crash the system, or to prevent + normal activities (disk/port i/o) from occuring. Using this function is considered very harmful, and it should only ever be used to protect data that could also be accessed in interrupts. - It is quite possible to either crash the system, or to prevent - normal activities (disk/port i/o) from occuring. - INPUTS None. @@ -62,7 +61,7 @@ (*) On EXECSMP builds, Enable() only applies to the processor it is called from. Data which needs to be protected from - parallel access will also require a spinlock. + parallel access will also require a spinlock. EXAMPLE In most userspace code, you will not want to use this function. @@ -84,49 +83,20 @@ D(bug("[Exec] Enable()\n");) - IDNESTCOUNT_DEC; + /* Classic Enable(): + * - IDNestCnt-- + * - If negative, INTENA = $C000 (enable all) + */ + volatile UWORD *INTENA = (UWORD *)0xDFF09A; + + SysBase->IDNestCnt--; - D(bug("[Exec] Enable: IDNESTCOUNT = %d\n", IDNESTCOUNT_GET);) + D(bug("[Exec] Enable: IDNESTCOUNT = %d\n", SysBase->IDNestCnt);) - if (KernelBase) + if ((BYTE)SysBase->IDNestCnt < 0) { - if (IDNESTCOUNT_GET < 0) - { - D(bug("[Exec] Enable: Enabling interrupts\n");) - - /* The following stuff is not safe to call from within supervisor mode */ - if (!KrnIsSuper()) - { - KrnSti(); - - /* - * There's no dff09c like thing in x86 native which would allow - * us to set delayed (mark it as pending but it gets triggered - * only once interrupts are enabled again) software interrupt, - * so we check it manually here in Enable(), similar to Permit(). - */ - if (SysBase->SysFlags & SFF_SoftInt) - { - /* - * First we react on SFF_SoftInt by issuing KrnCause() call. This triggers - * the complete interrupt processing code in kernel, which implies also - * rescheduling if it becomes necessary. - */ - D(bug("[Exec] Enable: causing softints\n");) - KrnCause(); - } - - if ((TDNESTCOUNT_GET < 0) && FLAG_SCHEDSWITCH_ISSET) - { - /* - * If SFF_SoftInt hasn't been set, we have a chance that task switching - * is enabled and pending. We need to trigger it here in such a case. - */ - D(bug("[Exec] Enable: rescheduling\n");) - KrnSchedule(); - } - } - } + D(bug("[Exec] Enable: Enabling interrupts\n");) + *INTENA = 0xC000; } AROS_LIBFUNC_EXIT diff --git a/rom/exec/remintserver.c b/rom/exec/remintserver.c index ca54fbce63e..d4d4ad5313f 100644 --- a/rom/exec/remintserver.c +++ b/rom/exec/remintserver.c @@ -1,5 +1,5 @@ /* - Copyright © 1995-2017, The AROS Development Team. All rights reserved. + Copyright © 1995-2017, The AROS Development Team. All rights reserved. $Id$ Desc: Remove an interrupt handler. @@ -57,12 +57,20 @@ return; } - EXEC_LOCK_LIST_WRITE_AND_DISABLE(&SysBase->IntrList); - - Remove((struct Node *)interrupt); - CUSTOM_DISABLE(intNumber, SysBase->IntVects[intNumber].iv_Data); - - EXEC_UNLOCK_LIST_AND_ENABLE(&SysBase->IntrList); + /* ------------------------------------------------------------ + * Disable() — classic Exec + * ------------------------------------------------------------ */ + Disable(); + + /* ------------------------------------------------------------ + * Remove the interrupt server from the list + * ------------------------------------------------------------ */ + Remove(&interrupt->is_Node); + + /* ------------------------------------------------------------ + * Enable() — classic Exec + * ------------------------------------------------------------ */ + Enable(); AROS_LIBFUNC_EXIT } /* RemIntServer */