KallistiOS
##version##
|
Interrupt and exception handling. More...
Go to the source code of this file.
Data Structures | |
struct | irq_context |
Architecture-specific structure for holding the processor state. More... | |
Macros | |
#define | REG_BYTE_CNT 256 /* Currently really 228 */ |
The number of bytes required to save thread context. More... | |
#define | CONTEXT_PC(c) ((c).pc) |
Fetch the program counter from an irq_context_t. More... | |
#define | CONTEXT_FP(c) ((c).r[14]) |
Fetch the frame pointer from an irq_context_t. More... | |
#define | CONTEXT_SP(c) ((c).r[15]) |
Fetch the stack pointer from an irq_context_t. More... | |
#define | CONTEXT_RET(c) ((c).r[0]) |
Fetch the return value from an irq_context_t. More... | |
#define | EXC_RESET_POWERON 0x0000 |
Power-on reset. More... | |
#define | EXC_RESET_MANUAL 0x0020 |
Manual reset. More... | |
#define | EXC_RESET_UDI 0x0000 |
Hitachi UDI reset. More... | |
#define | EXC_ITLB_MULTIPLE 0x0140 |
Instruction TLB multiple hit. More... | |
#define | EXC_DTLB_MULTIPLE 0x0140 |
Data TLB multiple hit. More... | |
#define | EXC_USER_BREAK_PRE 0x01e0 |
User break before instruction. More... | |
#define | EXC_INSTR_ADDRESS 0x00e0 |
Instruction address. More... | |
#define | EXC_ITLB_MISS 0x0040 |
Instruction TLB miss. More... | |
#define | EXC_ITLB_PV 0x00a0 |
Instruction TLB protection violation. More... | |
#define | EXC_ILLEGAL_INSTR 0x0180 |
Illegal instruction. More... | |
#define | EXC_SLOT_ILLEGAL_INSTR 0x01a0 |
Slot illegal instruction. More... | |
#define | EXC_GENERAL_FPU 0x0800 |
General FPU exception. More... | |
#define | EXC_SLOT_FPU 0x0820 |
Slot FPU exception. More... | |
#define | EXC_DATA_ADDRESS_READ 0x00e0 |
Data address (read) More... | |
#define | EXC_DATA_ADDRESS_WRITE 0x0100 |
Data address (write) More... | |
#define | EXC_DTLB_MISS_READ 0x0040 |
Data TLB miss (read) More... | |
#define | EXC_DTLB_MISS_WRITE 0x0060 |
Data TLB miss (write) More... | |
#define | EXC_DTLB_PV_READ 0x00a0 |
Data TLB protection violation (read) More... | |
#define | EXC_DTLB_PV_WRITE 0x00c0 |
Data TLB protection violation (write) More... | |
#define | EXC_FPU 0x0120 |
FPU exception. More... | |
#define | EXC_INITIAL_PAGE_WRITE 0x0080 |
Initial page write exception. More... | |
#define | EXC_TRAPA 0x0160 |
Unconditional trap (trapa) More... | |
#define | EXC_USER_BREAK_POST 0x01e0 |
User break after instruction. More... | |
#define | EXC_NMI 0x01c0 |
Nonmaskable interrupt. More... | |
#define | EXC_IRQ0 0x0200 |
External IRQ request (level 0) More... | |
#define | EXC_IRQ1 0x0220 |
External IRQ request (level 1) More... | |
#define | EXC_IRQ2 0x0240 |
External IRQ request (level 2) More... | |
#define | EXC_IRQ3 0x0260 |
External IRQ request (level 3) More... | |
#define | EXC_IRQ4 0x0280 |
External IRQ request (level 4) More... | |
#define | EXC_IRQ5 0x02a0 |
External IRQ request (level 5) More... | |
#define | EXC_IRQ6 0x02c0 |
External IRQ request (level 6) More... | |
#define | EXC_IRQ7 0x02e0 |
External IRQ request (level 7) More... | |
#define | EXC_IRQ8 0x0300 |
External IRQ request (level 8) More... | |
#define | EXC_IRQ9 0x0320 |
External IRQ request (level 9) More... | |
#define | EXC_IRQA 0x0340 |
External IRQ request (level 10) More... | |
#define | EXC_IRQB 0x0360 |
External IRQ request (level 11) More... | |
#define | EXC_IRQC 0x0380 |
External IRQ request (level 12) More... | |
#define | EXC_IRQD 0x03a0 |
External IRQ request (level 13) More... | |
#define | EXC_IRQE 0x03c0 |
External IRQ request (level 14) More... | |
#define | EXC_TMU0_TUNI0 0x0400 |
TMU0 underflow. More... | |
#define | EXC_TMU1_TUNI1 0x0420 |
TMU1 underflow. More... | |
#define | EXC_TMU2_TUNI2 0x0440 |
TMU2 underflow. More... | |
#define | EXC_TMU2_TICPI2 0x0460 |
TMU2 input capture. More... | |
#define | EXC_RTC_ATI 0x0480 |
RTC alarm interrupt. More... | |
#define | EXC_RTC_PRI 0x04a0 |
RTC periodic interrupt. More... | |
#define | EXC_RTC_CUI 0x04c0 |
RTC carry interrupt. More... | |
#define | EXC_SCI_ERI 0x04e0 |
SCI Error receive. More... | |
#define | EXC_SCI_RXI 0x0500 |
SCI Receive ready. More... | |
#define | EXC_SCI_TXI 0x0520 |
SCI Transmit ready. More... | |
#define | EXC_SCI_TEI 0x0540 |
SCI Transmit error. More... | |
#define | EXC_WDT_ITI 0x0560 |
Watchdog timer. More... | |
#define | EXC_REF_RCMI 0x0580 |
Memory refresh compare-match interrupt. More... | |
#define | EXC_REF_ROVI 0x05a0 |
Memory refresh counter overflow interrupt. More... | |
#define | EXC_UDI 0x0600 |
Hitachi UDI. More... | |
#define | EXC_GPIO_GPIOI 0x0620 |
I/O port interrupt. More... | |
#define | EXC_DMAC_DMTE0 0x0640 |
DMAC transfer end (channel 0) More... | |
#define | EXC_DMAC_DMTE1 0x0660 |
DMAC transfer end (channel 1) More... | |
#define | EXC_DMAC_DMTE2 0x0680 |
DMAC transfer end (channel 2) More... | |
#define | EXC_DMAC_DMTE3 0x06a0 |
DMAC transfer end (channel 3) More... | |
#define | EXC_DMA_DMAE 0x06c0 |
DMAC address error. More... | |
#define | EXC_SCIF_ERI 0x0700 |
SCIF Error receive. More... | |
#define | EXC_SCIF_RXI 0x0720 |
SCIF Receive ready. More... | |
#define | EXC_SCIF_BRI 0x0740 |
SCIF break. More... | |
#define | EXC_SCIF_TXI 0x0760 |
SCIF Transmit ready. More... | |
#define | EXC_DOUBLE_FAULT 0x0ff0 |
Double fault. More... | |
#define | EXC_UNHANDLED_EXC 0x0fe0 |
Unhandled exception. More... | |
#define | TIMER_IRQ EXC_TMU0_TUNI0 |
The value of the timer IRQ. More... | |
#define | EXC_OFFSET_000 0 |
irq_type_offsets Exception type offsets More... | |
#define | EXC_OFFSET_100 1 |
Offset 0x100. More... | |
#define | EXC_OFFSET_400 2 |
Offset 0x400. More... | |
#define | EXC_OFFSET_600 3 |
Offset 0x600. More... | |
Typedefs | |
typedef struct irq_context | irq_context_t |
Architecture-specific structure for holding the processor state. More... | |
typedef uint32 | irq_t |
The type of an interrupt identifier. More... | |
typedef void(* | irq_handler )(irq_t source, irq_context_t *context) |
The type of an IRQ handler. More... | |
Functions | |
int | irq_inside_int () |
Are we inside an interrupt handler? More... | |
void | irq_force_return () |
Pretend like we just came in from an interrupt and force a context switch back to the "current" context. More... | |
int | irq_set_handler (irq_t source, irq_handler hnd) |
Set or remove an IRQ handler. More... | |
irq_handler | irq_get_handler (irq_t source) |
Get the address of the current handler for the IRQ type. More... | |
int | trapa_set_handler (irq_t code, irq_handler hnd) |
Set or remove a handler for a trapa code. More... | |
int | irq_set_global_handler (irq_handler hnd) |
Set a global exception handler. More... | |
irq_handler | irq_get_global_handler () |
Get the global exception handler. More... | |
void | irq_set_context (irq_context_t *regbank) |
Switch out contexts (for interrupt return). More... | |
irq_context_t * | irq_get_context () |
Get the current IRQ context. More... | |
void | irq_create_context (irq_context_t *context, uint32 stack_pointer, uint32 routine, uint32 *args, int usermode) |
Fill a newly allocated context block for usage with supervisor or user mode. More... | |
int | irq_disable () |
Disable interrupts. More... | |
void | irq_enable () |
Enable all interrupts. More... | |
void | irq_restore (int v) |
Restore IRQ state. More... | |
int | irq_init () |
Initialize interrupts. More... | |
void | irq_shutdown () |
Shutdown interrupts, restoring the state to how it was before irq_init() was called. More... | |
Interrupt and exception handling.
This file contains various definitions and declarations related to handling interrupts and exceptions on the Dreamcast. This level deals with IRQs and exceptions generated on the SH4, versus the asic layer which deals with actually differentiating "external" interrupts.
#define CONTEXT_FP | ( | c | ) | ((c).r[14]) |
Fetch the frame pointer from an irq_context_t.
c | The context to read from. |
#define CONTEXT_PC | ( | c | ) | ((c).pc) |
Fetch the program counter from an irq_context_t.
c | The context to read from. |
#define CONTEXT_RET | ( | c | ) | ((c).r[0]) |
Fetch the return value from an irq_context_t.
c | The context to read from. |
#define CONTEXT_SP | ( | c | ) | ((c).r[15]) |
Fetch the stack pointer from an irq_context_t.
c | The context to read from. |
#define EXC_OFFSET_000 0 |
irq_type_offsets Exception type offsets
The following are a table of "type offsets" (see the Hitachi PDF). These are the 0x000, 0x100, 0x400, and 0x600 offsets.Offset 0x000
#define EXC_OFFSET_100 1 |
Offset 0x100.
#define EXC_OFFSET_400 2 |
Offset 0x400.
#define EXC_OFFSET_600 3 |
Offset 0x600.
#define REG_BYTE_CNT 256 /* Currently really 228 */ |
The number of bytes required to save thread context.
This should include all general CPU registers, FP registers, and status regs (even if not all of these are actually used).
On the Dreamcast, we need 228 bytes for all of that, but we round it up to a nicer number for sanity.
#define TIMER_IRQ EXC_TMU0_TUNI0 |
The value of the timer IRQ.
typedef struct irq_context irq_context_t |
Architecture-specific structure for holding the processor state.
This structure should hold register values and other important parts of the processor state. The size of this structure should be less than or equal to the REG_BYTE_CNT value.
typedef void(* irq_handler)(irq_t source, irq_context_t *context) |
The type of an IRQ handler.
source | The IRQ that caused the handler to be called. |
context | The CPU's context. |
void irq_create_context | ( | irq_context_t * | context, |
uint32 | stack_pointer, | ||
uint32 | routine, | ||
uint32 * | args, | ||
int | usermode | ||
) |
Fill a newly allocated context block for usage with supervisor or user mode.
The given parameters will be passed to the called routine (up to the architecture maximum). For the Dreamcast, this maximum is 4.
context | The IRQ context to fill in. |
stack_pointer | The value to set in the stack pointer. |
routine | The address of the program counter for the context. |
args | Any arguments to set in the registers. This cannot be NULL, and must have enough values to fill in up to the architecture maximum. |
usermode | 1 to run the routine in user mode, 0 for supervisor. |
int irq_disable | ( | ) |
Disable interrupts.
This function will disable interrupts, but will leave exceptions enabled.
void irq_enable | ( | ) |
Enable all interrupts.
This function will enable ALL interrupts, including external ones.
void irq_force_return | ( | ) |
Pretend like we just came in from an interrupt and force a context switch back to the "current" context.
Make sure you've called irq_set_context() before doing this!
irq_context_t* irq_get_context | ( | ) |
Get the current IRQ context.
This will fetch the processor context prior to the exception handling during an IRQ service routine.
irq_handler irq_get_global_handler | ( | ) |
Get the global exception handler.
irq_handler irq_get_handler | ( | irq_t | source | ) |
Get the address of the current handler for the IRQ type.
source | The IRQ type to look up. |
int irq_init | ( | ) |
Initialize interrupts.
0 | On success (no error conditions defined). |
int irq_inside_int | ( | ) |
Are we inside an interrupt handler?
1 | If interrupt handling is in progress. |
0 | If normal processing is in progress. |
void irq_restore | ( | int | v | ) |
Restore IRQ state.
This function will restore the interrupt state to the value specified. This should correspond to a value returned by irq_disable().
v | The IRQ state to restore. This should be a value returned by irq_disable(). |
void irq_set_context | ( | irq_context_t * | regbank | ) |
Switch out contexts (for interrupt return).
This function will set the processor state that will be restored when the exception returns.
regbank | The values of all registers to be restored. |
int irq_set_global_handler | ( | irq_handler | hnd | ) |
Set a global exception handler.
This function sets a global catch-all handler for all exception types.
hnd | A pointer to the procedure to handle the exception. |
0 | On success (no error conditions defined). |
int irq_set_handler | ( | irq_t | source, |
irq_handler | hnd | ||
) |
Set or remove an IRQ handler.
Passing a NULL value for hnd will remove the current handler, if any.
source | The IRQ type to set the handler for (see SH4 exception codes). |
hnd | A pointer to a procedure to handle the exception. |
0 | On success. |
-1 | If the source is invalid. |
void irq_shutdown | ( | ) |
Shutdown interrupts, restoring the state to how it was before irq_init() was called.
int trapa_set_handler | ( | irq_t | code, |
irq_handler | hnd | ||
) |
Set or remove a handler for a trapa code.
code | The value passed to the trapa opcode. |
hnd | A pointer to the procedure to handle the trap. |
0 | On success. |
-1 | If the code is invalid (greater than 0xFF). |