Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions rom/exec/addintserver.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
25 changes: 13 additions & 12 deletions rom/exec/disable.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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.

******************************************************************************/
{
Expand All @@ -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() */
60 changes: 15 additions & 45 deletions rom/exec/enable.c
Original file line number Diff line number Diff line change
@@ -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().
Expand Down Expand Up @@ -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.

Expand All @@ -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.
Expand All @@ -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
Expand Down
22 changes: 15 additions & 7 deletions rom/exec/remintserver.c
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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 */