libdragon
|
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_link * | AI_callback = 0 |
Linked list of AI callbacks. | |
struct callback_link * | VI_callback = 0 |
Linked list of VI callbacks. | |
struct callback_link * | PI_callback = 0 |
Linked list of PI callbacks. | |
struct callback_link * | DP_callback = 0 |
Linked list of DP callbacks. | |
struct callback_link * | TI_callback = 0 |
Linked list of TI callbacks. | |
struct callback_link * | SI_callback = 0 |
Linked list of SI callbacks. | |
struct callback_link * | SP_callback = 0 |
Linked list of SP callbacks. |
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.
enum interrupt_state_t |
static void __call_callback | ( | struct callback_link * | head | ) | [static] |
Call each callback in a linked list of callbacks.
[in] | head | Pointer to the head of a callback linke list |
void __MI_handler | ( | void | ) |
Handle an MI interrupt.
static void __register_callback | ( | struct callback_link ** | head, |
void(*)() | callback | ||
) | [static] |
Add a callback to a linked list of callbacks.
[in,out] | head | Pointer to the head of a linked list to add to |
[in] | callback | Function 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.
[in,out] | head | Pointer to the head of a linked list to remove from |
[in] | callback | Function to search for and remove from callback list |
void disable_interrupts | ( | ) |
Disable interrupts systemwide.
void enable_interrupts | ( | ) |
Enable interrupts systemwide.
Return the current state of interrupts.
INTERRUPTS_UNINITIALIZED | if the interrupt system has not been initialized yet. |
INTERRUPTS_DISABLED | if interrupts have been disabled for some reason. |
INTERRUPTS_ENABLED | if interrupts are currently enabled. |
void register_AI_handler | ( | void(*)() | callback | ) |
Register an AI callback.
[in] | callback | Function to call when an AI interrupt occurs |
void register_DP_handler | ( | void(*)() | callback | ) |
Register a DP callback.
[in] | callback | Function to call when a DP interrupt occurs |
void register_PI_handler | ( | void(*)() | callback | ) |
Register a PI callback.
[in] | callback | Function to call when a PI interrupt occurs |
void register_SI_handler | ( | void(*)() | callback | ) |
Register a SI callback.
[in] | callback | Function to call when a SI interrupt occurs |
void register_SP_handler | ( | void(*)() | callback | ) |
Register a SP callback.
[in] | callback | Function to call when a SP interrupt occurs |
void register_TI_handler | ( | void(*)() | callback | ) |
Register a TI callback.
[in] | callback | Function to call when a TI interrupt occurs |
void register_VI_handler | ( | void(*)() | callback | ) |
Register a VI callback.
[in] | callback | Function to call when a VI interrupt occurs |
void set_AI_interrupt | ( | int | active | ) |
Enable or disable the AI interrupt.
[in] | active | Flag to specify whether the AI interupt should be active |
void set_DP_interrupt | ( | int | active | ) |
Enable or disable the DP interrupt.
[in] | active | Flag to specify whether the DP interupt should be active |
void set_PI_interrupt | ( | int | active | ) |
Enable or disable the PI interrupt.
[in] | active | Flag to specify whether the PI interupt should be active |
void set_SI_interrupt | ( | int | active | ) |
Enable or disable the SI interrupt.
[in] | active | Flag to specify whether the SI interupt should be active |
void set_SP_interrupt | ( | int | active | ) |
Enable or disable the SP interrupt.
[in] | active | Flag to specify whether the SP interupt should be active |
void set_VI_interrupt | ( | int | active, |
unsigned long | line | ||
) |
Enable or disable the VI interrupt.
[in] | active | Flag to specify whether the VI interupt should be active |
[in] | line | The vertical line that causes this interrupt to fire. Ignored when setting the interrupt inactive |
void unregister_AI_handler | ( | void(*)() | callback | ) |
Unregister an AI callback.
[in] | callback | Function that should no longer be called on AI interrupts |
void unregister_DP_handler | ( | void(*)() | callback | ) |
Unregister a DP callback.
[in] | callback | Function that should no longer be called on DP interrupts |
void unregister_PI_handler | ( | void(*)() | callback | ) |
Unegister a PI callback.
[in] | callback | Function that should no longer be called on PI interrupts |
void unregister_SI_handler | ( | void(*)() | callback | ) |
Unegister a SI callback.
[in] | callback | Function that should no longer be called on SI interrupts |
void unregister_SP_handler | ( | void(*)() | callback | ) |
Unegister a SP callback.
[in] | callback | Function that should no longer be called on SP interrupts |
void unregister_TI_handler | ( | void(*)() | callback | ) |
Unegister a TI callback.
[in] | callback | Function that should no longer be called on TI interrupts |
void unregister_VI_handler | ( | void(*)() | callback | ) |
Unregister a VI callback.
[in] | callback | Function that should no longer be called on VI interrupts |
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.