libdragon
Data Structures | Files | Defines | Typedefs | Enumerations | Functions | Variables
Interrupt Controller
Low Level Hardware Interfaces

N64 interrupt registering and servicing routines. More...

Data Structures

struct  callback_link
 Structure of an interrupt callback. More...

Files

file  interrupt.c
 

Interrupt Controller.


file  interrupt.h
 

Interrupt Controller.


Defines

#define MI_INTR_SP   0x01
 SP interrupt bit.
#define MI_INTR_SI   0x02
 SI interrupt bit.
#define MI_INTR_AI   0x04
 AI interrupt bit.
#define MI_INTR_VI   0x08
 VI interrupt bit.
#define MI_INTR_PI   0x10
 PI interrupt bit.
#define MI_INTR_DP   0x20
 DP interrupt bit.
#define MI_MASK_SP   0x01
 SP mask bit.
#define MI_MASK_SI   0x02
 SI mask bit.
#define MI_MASK_AI   0x04
 AI mask bit.
#define MI_MASK_VI   0x08
 VI mask bit.
#define MI_MASK_PI   0x10
 PI mask bit.
#define MI_MASK_DP   0x20
 DP mask bit.
#define MI_MASK_CLR_SP   0x0001
 Clear SP mask.
#define MI_MASK_SET_SP   0x0002
 Set SP mask.
#define MI_MASK_CLR_SI   0x0004
 Clear SI mask.
#define MI_MASK_SET_SI   0x0008
 Set SI mask.
#define MI_MASK_CLR_AI   0x0010
 Clear AI mask.
#define MI_MASK_SET_AI   0x0020
 Set AI mask.
#define MI_MASK_CLR_VI   0x0040
 Clear VI mask.
#define MI_MASK_SET_VI   0x0080
 Set VI mask.
#define MI_MASK_CLR_PI   0x0100
 Clear PI mask.
#define MI_MASK_SET_PI   0x0200
 Set PI mask.
#define MI_MASK_CLR_DP   0x0400
 Clear DP mask.
#define MI_MASK_SET_DP   0x0800
 Set DP mask.
#define PI_CLEAR_INTERRUPT   0x02
 Bit to set to clear the PI interrupt.
#define SI_CLEAR_INTERRUPT   0
 Bit to set to clear the SI interrupt.
#define SP_CLEAR_INTERRUPT   0x08
 Bit to set to clear the SP interrupt.
#define DP_CLEAR_INTERRUPT   0x0800
 Bit to set to clear the DP interrupt.
#define AI_CLEAR_INTERRUPT   0
 Bit to set to clear the AI interrupt.

Typedefs

typedef struct callback_link _callback_link
 Structure of an interrupt callback.

Enumerations

enum  interrupt_state_t { INTERRUPTS_UNINITIALIZED, INTERRUPTS_DISABLED, INTERRUPTS_ENABLED }
 State of interrupts on the system. More...

Functions

static void __call_callback (struct callback_link *head)
 Call each callback in a linked list of callbacks.
static void __register_callback (struct callback_link **head, void(*callback)())
 Add a callback to a linked list of callbacks.
static void __unregister_callback (struct callback_link **head, void(*callback)())
 Remove a callback from a linked list of callbacks.
void __MI_handler (void)
 Handle an MI interrupt.
void __TI_handler (void)
 Handle a timer interrupt.
void register_AI_handler (void(*callback)())
 Register an AI callback.
void unregister_AI_handler (void(*callback)())
 Unregister an AI callback.
void register_VI_handler (void(*callback)())
 Register a VI callback.
void unregister_VI_handler (void(*callback)())
 Unregister a VI callback.
void register_PI_handler (void(*callback)())
 Register a PI callback.
void unregister_PI_handler (void(*callback)())
 Unegister a PI callback.
void register_DP_handler (void(*callback)())
 Register a DP callback.
void unregister_DP_handler (void(*callback)())
 Unregister a DP callback.
void register_TI_handler (void(*callback)())
 Register a TI callback.
void unregister_TI_handler (void(*callback)())
 Unegister a TI callback.
void register_SI_handler (void(*callback)())
 Register a SI callback.
void unregister_SI_handler (void(*callback)())
 Unegister a SI callback.
void register_SP_handler (void(*callback)())
 Register a SP callback.
void unregister_SP_handler (void(*callback)())
 Unegister a SP callback.
void set_AI_interrupt (int active)
 Enable or disable the AI interrupt.
void set_VI_interrupt (int active, unsigned long line)
 Enable or disable the VI interrupt.
void set_PI_interrupt (int active)
 Enable or disable the PI interrupt.
void set_DP_interrupt (int active)
 Enable or disable the DP interrupt.
void set_SI_interrupt (int active)
 Enable or disable the SI interrupt.
void set_SP_interrupt (int active)
 Enable or disable the SP interrupt.
void init_interrupts ()
 Initialize the interrupt controller.
void disable_interrupts ()
 Disable interrupts systemwide.
void enable_interrupts ()
 Enable interrupts systemwide.
interrupt_state_t get_interrupts_state ()
 Return the current state of interrupts.

Variables

static int __interrupt_depth = -1
 Number of nested disable interrupt calls.
static struct AI_regs_s *const AI_regs = (struct AI_regs_s *)0xa4500000
 Static structure to address AI registers.
static struct MI_regs_s *const MI_regs = (struct MI_regs_s *)0xa4300000
 Static structure to address MI registers.
static struct VI_regs_s *const VI_regs = (struct VI_regs_s *)0xa4400000
 Static structure to address VI registers.
static struct PI_regs_s *const PI_regs = (struct PI_regs_s *)0xa4600000
 Static structure to address PI registers.
static struct SI_regs_s *const SI_regs = (struct SI_regs_s *)0xa4800000
 Static structure to address SI registers.
static struct SP_regs_s *const SP_regs = (struct SP_regs_s *)0xa4040000
 Static structure to address SP registers.
struct callback_linkAI_callback = 0
 Linked list of AI callbacks.
struct callback_linkVI_callback = 0
 Linked list of VI callbacks.
struct callback_linkPI_callback = 0
 Linked list of PI callbacks.
struct callback_linkDP_callback = 0
 Linked list of DP callbacks.
struct callback_linkTI_callback = 0
 Linked list of TI callbacks.
struct callback_linkSI_callback = 0
 Linked list of SI callbacks.
struct callback_linkSP_callback = 0
 Linked list of SP callbacks.

Detailed Description

N64 interrupt registering and servicing routines.

The N64 interrupt controller provides a software interface to register for interrupts from the various systems in the N64. Most interrupts on the N64 coordinate through the MIPS interface (MI) to allow interrupts to be handled at one spot. A notable exception is the timer interrupt which is generated by the MIPS r4300 itself and not the N64 hardware.

Before interrupts can be used on the system, the interrupt controller should be configured using init_interrupts. Once this is done, interrupts are enabled and any registered callback can be called when an interrupt occurs. Each of the N64-generated interrupts is maskable using the various set accessors.

Interrupts can be enabled or disabled as a whole on the N64 using enable_interrupts and disable_interrupts. It is assumed that once the interrupt system is activated, these will always be called in pairs. Calling enable_interrupts without first calling disable_interrupts is considered a violation of this assumption and should be avoided. Calling disable_interrupts when interrupts are already disabled will have no effect. Calling enable_interrupts again to restore from a critical section will not enable interrupts if interrupts were not enabled when calling disable_interrupts. In this manner, it is safe to nest calls to disable and enable interrupts.


Enumeration Type Documentation

State of interrupts on the system.

Enumerator:
INTERRUPTS_UNINITIALIZED 

Interrupt controller has not been initialized.

INTERRUPTS_DISABLED 

Interrupts are currently disabled.

INTERRUPTS_ENABLED 

Interrupts are currently enabled.


Function Documentation

static void __call_callback ( struct callback_link head) [static]

Call each callback in a linked list of callbacks.

Parameters:
[in]headPointer to the head of a callback linke list
void __MI_handler ( void  )

Handle an MI interrupt.

Note:
This function handles most of the interrupts on the system as they come through the MI.
static void __register_callback ( struct callback_link **  head,
void(*)()  callback 
) [static]

Add a callback to a linked list of callbacks.

Parameters:
[in,out]headPointer to the head of a linked list to add to
[in]callbackFunction to call when executing callbacks in this linked list
static void __unregister_callback ( struct callback_link **  head,
void(*)()  callback 
) [static]

Remove a callback from a linked list of callbacks.

Parameters:
[in,out]headPointer to the head of a linked list to remove from
[in]callbackFunction to search for and remove from callback list

Disable interrupts systemwide.

Note:
If interrupts are already disabled on the system or interrupts have not been initialized, this function will not modify the system state.

Enable interrupts systemwide.

Note:
If this is called inside a nested disable call, it will have no effect on the system. Therefore it is safe to nest disable/enable calls. After the last nested interrupt is enabled, systemwide interrupts will be reenabled.

Return the current state of interrupts.

Return values:
INTERRUPTS_UNINITIALIZEDif the interrupt system has not been initialized yet.
INTERRUPTS_DISABLEDif interrupts have been disabled for some reason.
INTERRUPTS_ENABLEDif interrupts are currently enabled.
void register_AI_handler ( void(*)()  callback)

Register an AI callback.

Parameters:
[in]callbackFunction to call when an AI interrupt occurs
void register_DP_handler ( void(*)()  callback)

Register a DP callback.

Parameters:
[in]callbackFunction to call when a DP interrupt occurs
void register_PI_handler ( void(*)()  callback)

Register a PI callback.

Parameters:
[in]callbackFunction to call when a PI interrupt occurs
void register_SI_handler ( void(*)()  callback)

Register a SI callback.

Parameters:
[in]callbackFunction to call when a SI interrupt occurs
void register_SP_handler ( void(*)()  callback)

Register a SP callback.

Parameters:
[in]callbackFunction to call when a SP interrupt occurs
void register_TI_handler ( void(*)()  callback)

Register a TI callback.

Parameters:
[in]callbackFunction to call when a TI interrupt occurs
void register_VI_handler ( void(*)()  callback)

Register a VI callback.

Parameters:
[in]callbackFunction to call when a VI interrupt occurs
void set_AI_interrupt ( int  active)

Enable or disable the AI interrupt.

Parameters:
[in]activeFlag to specify whether the AI interupt should be active
void set_DP_interrupt ( int  active)

Enable or disable the DP interrupt.

Parameters:
[in]activeFlag to specify whether the DP interupt should be active
void set_PI_interrupt ( int  active)

Enable or disable the PI interrupt.

Parameters:
[in]activeFlag to specify whether the PI interupt should be active
void set_SI_interrupt ( int  active)

Enable or disable the SI interrupt.

Parameters:
[in]activeFlag to specify whether the SI interupt should be active
void set_SP_interrupt ( int  active)

Enable or disable the SP interrupt.

Parameters:
[in]activeFlag to specify whether the SP interupt should be active
void set_VI_interrupt ( int  active,
unsigned long  line 
)

Enable or disable the VI interrupt.

Parameters:
[in]activeFlag to specify whether the VI interupt should be active
[in]lineThe vertical line that causes this interrupt to fire. Ignored when setting the interrupt inactive
void unregister_AI_handler ( void(*)()  callback)

Unregister an AI callback.

Parameters:
[in]callbackFunction that should no longer be called on AI interrupts
void unregister_DP_handler ( void(*)()  callback)

Unregister a DP callback.

Parameters:
[in]callbackFunction that should no longer be called on DP interrupts
void unregister_PI_handler ( void(*)()  callback)

Unegister a PI callback.

Parameters:
[in]callbackFunction that should no longer be called on PI interrupts
void unregister_SI_handler ( void(*)()  callback)

Unegister a SI callback.

Parameters:
[in]callbackFunction that should no longer be called on SI interrupts
void unregister_SP_handler ( void(*)()  callback)

Unegister a SP callback.

Parameters:
[in]callbackFunction that should no longer be called on SP interrupts
void unregister_TI_handler ( void(*)()  callback)

Unegister a TI callback.

Parameters:
[in]callbackFunction that should no longer be called on TI interrupts
void unregister_VI_handler ( void(*)()  callback)

Unregister a VI callback.

Parameters:
[in]callbackFunction that should no longer be called on VI interrupts

Variable Documentation

int __interrupt_depth = -1 [static]

Number of nested disable interrupt calls.

This will represent the number of disable interrupt calls made on the system. If this is set to 0, interrupts are enabled. A number higher than 0 represents that many disable calls that were nested, and consequently the number of interrupt enable calls that need to be made to re-enable interrupts. A negative number means that the interrupt system hasn't been initialized yet.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines