From: falcovorbis <fal...@us...> - 2024-10-12 07:04:01
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 45525d79ba9ec9a3dd17f45a8ed3c4cf8bf77053 (commit) from 0b6686cdbee523cf32968c20faaa12f3174a64f4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 45525d79ba9ec9a3dd17f45a8ed3c4cf8bf77053 Author: Donald Haase <qu...@ya...> Date: Sat Oct 12 03:03:23 2024 -0400 * Refactor and cleanup of IRQ system. (#815) * Authored by Falco Girgis * Retype interrupt codes to an enum. * Use stdint and bool types where possible. * Various minor code cleanups. * Restructure layout and doxygen in header. * Clean up register accesses in irq.c to match other drivers. * Retype global handler into proper irq_cb type. Co-authored-by: QuzarDC <qu...@co...> ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/include/arch/irq.h | 582 +++++++++++++++++-------------- kernel/arch/dreamcast/kernel/irq.c | 126 ++++--- 2 files changed, 374 insertions(+), 334 deletions(-) diff --git a/kernel/arch/dreamcast/include/arch/irq.h b/kernel/arch/dreamcast/include/arch/irq.h index 0d3ce1c4..54c46889 100644 --- a/kernel/arch/dreamcast/include/arch/irq.h +++ b/kernel/arch/dreamcast/include/arch/irq.h @@ -2,10 +2,12 @@ arch/dreamcast/include/irq.h Copyright (C) 2000-2001 Megan Potter + Copyright (C) 2024 Paul Cercueil + Copyright (C) 2024 Falco Girgis */ -/** \file arch/irq.h +/** \file \brief Interrupt and exception handling. \ingroup irqs @@ -15,12 +17,16 @@ actually differentiating "external" interrupts. \author Megan Potter - \see dc/asic.h + \author Paul Cercueil + \author Falco Girgis + + \see dc/asic.h, arch/trap.h */ #ifndef __ARCH_IRQ_H #define __ARCH_IRQ_H +#include <stdbool.h> #include <stdint.h> #include <sys/cdefs.h> __BEGIN_DECLS @@ -33,218 +39,222 @@ __BEGIN_DECLS /** \defgroup irqs Interrupts \brief IRQs and ISRs for the SH4's CPU \ingroup system + + This is an API for managing interrupts, their masks, and their + handler routines along with thread context information. + + \warning + This is a low-level, internal kernel API. Many of these + interrupts are utilized by various KOS drivers and have higher-level APIs + for hooking into them. Care must be taken to not interfere with the IRQ + handling which is being done by in-use KOS drivers. + + @{ */ -/** \brief The number of bytes required to save thread context. - \ingroup irqs +/** \defgroup Context + \brief Thread execution state and accessors + + This API includes the structure and accessors for a + thread's context state, which contains the registers that are stored + and loaded upon thread context switches, which are passed back to + interrupt handlers. + + @{ +*/ + +/** 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 + \note + On the Dreamcast, we need `228` bytes for all of that, but we round it up to a nicer number for sanity. */ -#define REG_BYTE_CNT 256 /* Currently really 228 */ +#define REG_BYTE_CNT 256 -/** \brief Architecture-specific structure for holding the processor state. - \ingroup irqs +/** 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. - - \headerfile arch/irq.h -*/ -typedef struct irq_context { - uint32_t pc; /**< \brief Program counter */ - uint32_t pr; /**< \brief Procedure register (aka return address) */ - uint32_t gbr; /**< \brief Global base register */ - uint32_t vbr; /**< \brief Vector base register */ - uint32_t mach; /**< \brief Multiply-and-accumulate register (high) */ - uint32_t macl; /**< \brief Multiply-and-accumulate register (low) */ - uint32_t sr; /**< \brief Status register */ - uint32_t fpul; /**< \brief Floatint-point communication register */ - uint32_t fr[16]; /**< \brief Primary floating point registers */ - uint32_t frbank[16]; /**< \brief Secondary floating point registers */ - uint32_t r[16]; /**< \brief 16 general purpose (integer) registers */ - uint32_t fpscr; /**< \brief Floating-point status/control register */ -} irq_context_t __attribute__((aligned(32))); - -/* A couple of architecture independent access macros */ -/** \brief Fetch the program counter from an irq_context_t. - \ingroup irqs - + processor state. + + \note + The size of this structure should be less than or equal to the + \ref REG_BYTE_CNT value. +*/ +typedef __attribute__((aligned(32))) struct irq_context { + uint32_t pc; /**< Program counter */ + uint32_t pr; /**< Procedure register (aka return address) */ + uint32_t gbr; /**< Global base register (TLS segment ptr) */ + uint32_t vbr; /**< Vector base register */ + uint32_t mach; /**< Multiply-and-accumulate register (high) */ + uint32_t macl; /**< Multiply-and-accumulate register (low) */ + uint32_t sr; /**< Status register */ + uint32_t fpul; /**< Floating-point communication register */ + uint32_t fr[16]; /**< Primary floating point registers */ + uint32_t frbank[16]; /**< Secondary floating point registers */ + uint32_t r[16]; /**< 16 general purpose (integer) registers */ + uint32_t fpscr; /**< Floating-point status/control register */ +} irq_context_t; + +/** \name Register Accessors + \brief Convenience macros for accessing context registers + @{ +*/ +/** Fetch the program counter from an irq_context_t. \param c The context to read from. - \return The program counter value. */ #define CONTEXT_PC(c) ((c).pc) -/** \brief Fetch the frame pointer from an irq_context_t. - \ingroup irqs - +/** Fetch the frame pointer from an irq_context_t. \param c The context to read from. - \return The frame pointer value. */ #define CONTEXT_FP(c) ((c).r[14]) -/** \brief Fetch the stack pointer from an irq_context_t. - \ingroup irqs - +/** Fetch the stack pointer from an irq_context_t. \param c The context to read from. - \return The stack pointer value. */ #define CONTEXT_SP(c) ((c).r[15]) -/** \brief Fetch the return value from an irq_context_t. - \ingroup irqs - +/** Fetch the return value from an irq_context_t. \param c The context to read from. - \return The return value. */ #define CONTEXT_RET(c) ((c).r[0]) +/** @} */ -/** \defgroup irq_exception_codes Exception Codes - \brief IRQ exception code values - \ingroup irqs - - These are all of the exceptions that can be raised on the SH4, and their - codes. They're divided into several logical groups. +/** Switch out contexts (for interrupt return). - @{ -*/ -/* Dreamcast-specific exception codes.. use these when getting or setting an - exception code value. */ - -/** \defgroup irq_reset_codes Reset Type - \brief IRQ reset type codes + This function will set the processor state that will be restored when the + exception returns. - These are exceptions that essentially cause a reset of the system. They - cannot actually be caught by normal means. They will all automatically cause - a branch to address 0xA0000000. These are pretty much fatal. + \param regbank The values of all registers to be restored. - @{ + \sa irq_get_context() */ -#define EXC_RESET_POWERON 0x0000 /**< \brief Power-on reset */ -#define EXC_RESET_MANUAL 0x0020 /**< \brief Manual reset */ -#define EXC_RESET_UDI 0x0000 /**< \brief Hitachi UDI reset */ -#define EXC_ITLB_MULTIPLE 0x0140 /**< \brief Instruction TLB multiple hit */ -#define EXC_DTLB_MULTIPLE 0x0140 /**< \brief Data TLB multiple hit */ -/** @} */ - -/** \defgroup irq_reexec_codes Re-Execution Type - \brief IRQ re-execution type codes - - These exceptions will stop the currently processing instruction, and - transition into exception processing. After handling the exception (assuming - that it can be handled by the code), the offending instruction will be - re-executed from the start. +void irq_set_context(irq_context_t *regbank); - @{ -*/ -#define EXC_USER_BREAK_PRE 0x01e0 /**< \brief User break before instruction */ -#define EXC_INSTR_ADDRESS 0x00e0 /**< \brief Instruction address */ -#define EXC_ITLB_MISS 0x0040 /**< \brief Instruction TLB miss */ -#define EXC_ITLB_PV 0x00a0 /**< \brief Instruction TLB protection violation */ -#define EXC_ILLEGAL_INSTR 0x0180 /**< \brief Illegal instruction */ -#define EXC_SLOT_ILLEGAL_INSTR 0x01a0 /**< \brief Slot illegal instruction */ -#define EXC_GENERAL_FPU 0x0800 /**< \brief General FPU exception */ -#define EXC_SLOT_FPU 0x0820 /**< \brief Slot FPU exception */ -#define EXC_DATA_ADDRESS_READ 0x00e0 /**< \brief Data address (read) */ -#define EXC_DATA_ADDRESS_WRITE 0x0100 /**< \brief Data address (write) */ -#define EXC_DTLB_MISS_READ 0x0040 /**< \brief Data TLB miss (read) */ -#define EXC_DTLB_MISS_WRITE 0x0060 /**< \brief Data TLB miss (write) */ -#define EXC_DTLB_PV_READ 0x00a0 /**< \brief Data TLB protection violation (read) */ -#define EXC_DTLB_PV_WRITE 0x00c0 /**< \brief Data TLB protection violation (write) */ -#define EXC_FPU 0x0120 /**< \brief FPU exception */ -#define EXC_INITIAL_PAGE_WRITE 0x0080 /**< \brief Initial page write exception */ -/** @} */ +/** Get the current IRQ context. -/** \defgroup irq_completion_codes Completion Type - \brief IRQ completion type codes + This will fetch the processor context prior to the exception handling during + an IRQ service routine. - These exceptions are actually handled in-between instructions, allowing the - instruction that causes them to finish completely. The saved PC thus is the - value of the next instruction. + \return The current IRQ context. - @{ + \sa irq_set_context() */ -#define EXC_TRAPA 0x0160 /**< \brief Unconditional trap (trapa) */ -#define EXC_USER_BREAK_POST 0x01e0 /**< \brief User break after instruction */ -/** @} */ - -/** \defgroup irq_interrupt_codes Interrupt (Completion Type) - \brief IRQ interrupt completiion type codes +irq_context_t *irq_get_context(void); - \note Not all of these have any meaning on the Dreamcast. Those that have - no meaning are only included for completeness. +/** Fill a newly allocated context block. - These exceptions are caused by interrupt requests. These generally are from - peripheral devices, but NMIs, timer interrupts, and DMAC interrupts are also - included here. + The given parameters will be passed to the called routine (up to the + architecture maximum). For the Dreamcast, this maximum is 4. - @{ + \param context The IRQ context to fill in. + \param stack_pointer The value to set in the stack pointer. + \param routine The address of the program counter for the context. + \param 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. + \param usermode true to run the routine in user mode, false for + supervisor. */ -#define EXC_NMI 0x01c0 /**< \brief Nonmaskable interrupt */ -#define EXC_IRQ0 0x0200 /**< \brief External IRQ request (level 0) */ -#define EXC_IRQ1 0x0220 /**< \brief External IRQ request (level 1) */ -#define EXC_IRQ2 0x0240 /**< \brief External IRQ request (level 2) */ -#define EXC_IRQ3 0x0260 /**< \brief External IRQ request (level 3) */ -#define EXC_IRQ4 0x0280 /**< \brief External IRQ request (level 4) */ -#define EXC_IRQ5 0x02a0 /**< \brief External IRQ request (level 5) */ -#define EXC_IRQ6 0x02c0 /**< \brief External IRQ request (level 6) */ -#define EXC_IRQ7 0x02e0 /**< \brief External IRQ request (level 7) */ -#define EXC_IRQ8 0x0300 /**< \brief External IRQ request (level 8) */ -#define EXC_IRQ9 0x0320 /**< \brief External IRQ request (level 9) */ -#define EXC_IRQA 0x0340 /**< \brief External IRQ request (level 10) */ -#define EXC_IRQB 0x0360 /**< \brief External IRQ request (level 11) */ -#define EXC_IRQC 0x0380 /**< \brief External IRQ request (level 12) */ -#define EXC_IRQD 0x03a0 /**< \brief External IRQ request (level 13) */ -#define EXC_IRQE 0x03c0 /**< \brief External IRQ request (level 14) */ -#define EXC_TMU0_TUNI0 0x0400 /**< \brief TMU0 underflow */ -#define EXC_TMU1_TUNI1 0x0420 /**< \brief TMU1 underflow */ -#define EXC_TMU2_TUNI2 0x0440 /**< \brief TMU2 underflow */ -#define EXC_TMU2_TICPI2 0x0460 /**< \brief TMU2 input capture */ -#define EXC_RTC_ATI 0x0480 /**< \brief RTC alarm interrupt */ -#define EXC_RTC_PRI 0x04a0 /**< \brief RTC periodic interrupt */ -#define EXC_RTC_CUI 0x04c0 /**< \brief RTC carry interrupt */ -#define EXC_SCI_ERI 0x04e0 /**< \brief SCI Error receive */ -#define EXC_SCI_RXI 0x0500 /**< \brief SCI Receive ready */ -#define EXC_SCI_TXI 0x0520 /**< \brief SCI Transmit ready */ -#define EXC_SCI_TEI 0x0540 /**< \brief SCI Transmit error */ -#define EXC_WDT_ITI 0x0560 /**< \brief Watchdog timer */ -#define EXC_REF_RCMI 0x0580 /**< \brief Memory refresh compare-match interrupt */ -#define EXC_REF_ROVI 0x05a0 /**< \brief Memory refresh counter overflow interrupt */ -#define EXC_UDI 0x0600 /**< \brief Hitachi UDI */ -#define EXC_GPIO_GPIOI 0x0620 /**< \brief I/O port interrupt */ -#define EXC_DMAC_DMTE0 0x0640 /**< \brief DMAC transfer end (channel 0) */ -#define EXC_DMAC_DMTE1 0x0660 /**< \brief DMAC transfer end (channel 1) */ -#define EXC_DMAC_DMTE2 0x0680 /**< \brief DMAC transfer end (channel 2) */ -#define EXC_DMAC_DMTE3 0x06a0 /**< \brief DMAC transfer end (channel 3) */ -#define EXC_DMA_DMAE 0x06c0 /**< \brief DMAC address error */ -#define EXC_SCIF_ERI 0x0700 /**< \brief SCIF Error receive */ -#define EXC_SCIF_RXI 0x0720 /**< \brief SCIF Receive ready */ -#define EXC_SCIF_BRI 0x0740 /**< \brief SCIF break */ -#define EXC_SCIF_TXI 0x0760 /**< \brief SCIF Transmit ready */ -/** @} */ - -/** \brief Double fault +void irq_create_context(irq_context_t *context, uint32_t stack_pointer, + uint32_t routine, const uint32_t *args, bool usermode); - This exception is completely done in software (not represented on the CPU at - all). Its used for when an exception occurs during an IRQ service routine. -*/ -#define EXC_DOUBLE_FAULT 0x0ff0 +/** @} */ -/** \brief Unhandled exception +/** Interrupt exception codes + + Dreamcast-specific exception codes. Used to identify the source or type of + an interrupt. Each exception code is of a certain "type" which dictates how the interrupt + is generated and handled. + + List of exception types: + + |Type | Description + |--------|------------ + |`RESET` | Caused by system reset. Uncatchable and fatal. Automatically branch to address `0xA0000000`. + |`REEXEC`| Restarts current instruction after interrupt processing. Context PC is the triggering instruction. + |`POST` | Continues with next instruciton after interrupt processing. Context PC is the next instruction. + |`SOFT` | Software-driven exceptions for triggering interrupts upon special events. + |`UNUSED`| Known to not be present and usable with the DC's SH4 configuration. + + List of exception codes: +*/ +typedef enum irq_exception { + EXC_RESET_POWERON = 0x0000, /**< `[RESET ]` Power-on reset */ + EXC_RESET_MANUAL = 0x0020, /**< `[RESET ]` Manual reset */ + EXC_RESET_UDI = 0x0000, /**< `[RESET ]` Hitachi UDI reset */ + EXC_ITLB_MULTIPLE = 0x0140, /**< `[RESET ]` Instruction TLB multiple hit */ + EXC_DTLB_MULTIPLE = 0x0140, /**< `[RESET ]` Data TLB multiple hit */ + EXC_USER_BREAK_PRE = 0x01e0, /**< `[REEXEC]` User break before instruction */ + EXC_INSTR_ADDRESS = 0x00e0, /**< `[REEXEC]` Instruction address */ + EXC_ITLB_MISS = 0x0040, /**< `[REEXEC]` Instruction TLB miss */ + EXC_ITLB_PV = 0x00a0, /**< `[REEXEC]` Instruction TLB protection violation */ + EXC_ILLEGAL_INSTR = 0x0180, /**< `[REEXEC]` Illegal instruction */ + EXC_SLOT_ILLEGAL_INSTR = 0x01a0, /**< `[REEXEC]` Slot illegal instruction */ + EXC_GENERAL_FPU = 0x0800, /**< `[REEXEC]` General FPU exception */ + EXC_SLOT_FPU = 0x0820, /**< `[REEXEC]` Slot FPU exception */ + EXC_DATA_ADDRESS_READ = 0x00e0, /**< `[REEXEC]` Data address (read) */ + EXC_DATA_ADDRESS_WRITE = 0x0100, /**< `[REEXEC]` Data address (write) */ + EXC_DTLB_MISS_READ = 0x0040, /**< `[REEXEC]` Data TLB miss (read) */ + EXC_DTLB_MISS_WRITE = 0x0060, /**< `[REEXEC]` Data TLB miss (write) */ + EXC_DTLB_PV_READ = 0x00a0, /**< `[REEXEC]` Data TLB protection violation (read) */ + EXC_DTLB_PV_WRITE = 0x00c0, /**< `[REEXEC]` Data TLB protection violation (write) */ + EXC_FPU = 0x0120, /**< `[REEXEC]` FPU exception */ + EXC_INITIAL_PAGE_WRITE = 0x0080, /**< `[REEXEC]` Initial page write exception */ + EXC_TRAPA = 0x0160, /**< `[POST ]` Unconditional trap (`TRAPA`) */ + EXC_USER_BREAK_POST = 0x01e0, /**< `[POST ]` User break after instruction */ + EXC_NMI = 0x01c0, /**< `[POST ]` Nonmaskable interrupt */ + EXC_IRQ0 = 0x0200, /**< `[POST ]` External IRQ request (level 0) */ + EXC_IRQ1 = 0x0220, /**< `[POST ]` External IRQ request (level 1) */ + EXC_IRQ2 = 0x0240, /**< `[POST ]` External IRQ request (level 2) */ + EXC_IRQ3 = 0x0260, /**< `[POST ]` External IRQ request (level 3) */ + EXC_IRQ4 = 0x0280, /**< `[POST ]` External IRQ request (level 4) */ + EXC_IRQ5 = 0x02a0, /**< `[POST ]` External IRQ request (level 5) */ + EXC_IRQ6 = 0x02c0, /**< `[POST ]` External IRQ request (level 6) */ + EXC_IRQ7 = 0x02e0, /**< `[POST ]` External IRQ request (level 7) */ + EXC_IRQ8 = 0x0300, /**< `[POST ]` External IRQ request (level 8) */ + EXC_IRQ9 = 0x0320, /**< `[POST ]` External IRQ request (level 9) */ + EXC_IRQA = 0x0340, /**< `[POST ]` External IRQ request (level 10) */ + EXC_IRQB = 0x0360, /**< `[POST ]` External IRQ request (level 11) */ + EXC_IRQC = 0x0380, /**< `[POST ]` External IRQ request (level 12) */ + EXC_IRQD = 0x03a0, /**< `[POST ]` External IRQ request (level 13) */ + EXC_IRQE = 0x03c0, /**< `[POST ]` External IRQ request (level 14) */ + EXC_TMU0_TUNI0 = 0x0400, /**< `[POST ]` TMU0 underflow */ + EXC_TMU1_TUNI1 = 0x0420, /**< `[POST ]` TMU1 underflow */ + EXC_TMU2_TUNI2 = 0x0440, /**< `[POST ]` TMU2 underflow */ + EXC_TMU2_TICPI2 = 0x0460, /**< `[UNUSED]` TMU2 input capture */ + EXC_RTC_ATI = 0x0480, /**< `[UNUSED]` RTC alarm interrupt */ + EXC_RTC_PRI = 0x04a0, /**< `[UNUSED]` RTC periodic interrupt */ + EXC_RTC_CUI = 0x04c0, /**< `[UNUSED]` RTC carry interrupt */ + EXC_SCI_ERI = 0x04e0, /**< `[UNUSED]` SCI Error receive */ + EXC_SCI_RXI = 0x0500, /**< `[UNUSED]` SCI Receive ready */ + EXC_SCI_TXI = 0x0520, /**< `[UNUSED]` SCI Transmit ready */ + EXC_SCI_TEI = 0x0540, /**< `[UNUSED]` SCI Transmit error */ + EXC_WDT_ITI = 0x0560, /**< `[POST ]` Watchdog timer */ + EXC_REF_RCMI = 0x0580, /**< `[POST ]` Memory refresh compare-match interrupt */ + EXC_REF_ROVI = 0x05a0, /**< `[POST ]` Memory refresh counter overflow interrupt */ + EXC_UDI = 0x0600, /**< `[POST ]` Hitachi UDI */ + EXC_GPIO_GPIOI = 0x0620, /**< `[POST ]` I/O port interrupt */ + EXC_DMAC_DMTE0 = 0x0640, /**< `[POST ]` DMAC transfer end (channel 0) */ + EXC_DMAC_DMTE1 = 0x0660, /**< `[POST ]` DMAC transfer end (channel 1) */ + EXC_DMAC_DMTE2 = 0x0680, /**< `[POST ]` DMAC transfer end (channel 2) */ + EXC_DMAC_DMTE3 = 0x06a0, /**< `[POST ]` DMAC transfer end (channel 3) */ + EXC_DMA_DMAE = 0x06c0, /**< `[POST ]` DMAC address error */ + EXC_SCIF_ERI = 0x0700, /**< `[POST ]` SCIF Error receive */ + EXC_SCIF_RXI = 0x0720, /**< `[POST ]` SCIF Receive ready */ + EXC_SCIF_BRI = 0x0740, /**< `[POST ]` SCIF break */ + EXC_SCIF_TXI = 0x0760, /**< `[POST ]` SCIF Transmit ready */ + EXC_DOUBLE_FAULT = 0x0ff0, /**< `[SOFT ]` Exception happened in an ISR */ + EXC_UNHANDLED_EXC = 0x0fe0 /**< `[SOFT ]` Exception went unhandled */ +} irq_t; - This exception is a software-generated exception for a generic unhandled - exception. -*/ -#define EXC_UNHANDLED_EXC 0x0fe0 -/** @} */ /** \defgroup irq_type_offsets Exception type offsets \brief Offsets within exception types @@ -266,64 +276,157 @@ typedef struct irq_context { */ #define TIMER_IRQ EXC_TMU0_TUNI0 -/** \brief The type of an interrupt identifier - \ingroup irqs -*/ -typedef uint32_t irq_t; +/** \defgroup irq_state State + \brief Methods for querying active IRQ information. -/** \brief The type of an IRQ handler - \ingroup irqs + Provides an API for accessing the state of the current IRQ context such + as the active interrupt or whether it has been handled. - \param source The IRQ that caused the handler to be called. - \param context The CPU's context. + @{ */ -typedef void (*irq_handler)(irq_t source, irq_context_t *context, void *data); -/** \brief Are we inside an interrupt handler? - \ingroup irqs - \retval 1 If interrupt handling is in progress. +/** Returns whether inside of an interrupt context. + + \retval non-zero If interrupt handling is in progress. + ((code&0xf)<<16) | (evt&0xffff) \retval 0 If normal processing is in progress. + */ int irq_inside_int(void); -/** \brief Pretend like we just came in from an interrupt and force - a context switch back to the "current" context. - \ingroup irqs +/** @} */ + +/** \defgroup irq_mask Mask + \brief Accessors and modifiers of the IMASK state. + + This API is provided for managing and querying information regarding the + interrupt mask, a series of bitflags representing whether each type of + interrupt has been enabled or not. + + @{ +*/ + +/** Type representing an interrupt mask state. */ +typedef uint32_t irq_mask_t; +/** Disable interrupts. + + This function will disable interrupts, but will leave exceptions enabled. + + \return The state of IRQs before calling the function. This + can be used to restore this state later on with + irq_restore(). + + \sa irq_restore(), irq_enable() +*/ +irq_mask_t irq_disable(void); + +/** Enable all interrupts. + + This function will enable ALL interrupts, including external ones. + + \sa irq_disable() +*/ +void irq_enable(void); + +/** Restore IRQ state. + + This function will restore the interrupt state to the value specified. This + should correspond to a value returned by irq_disable(). + + \param v The IRQ state to restore. This should be a value + returned by irq_disable(). + + \sa irq_disable() +*/ +void irq_restore(irq_mask_t v); + ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |