summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/gba/irq
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2005-07-06 18:46:04 +0000
commit3c7ed6b8cd505f696c9c2b6d90723094f334b348 (patch)
tree30da596d32865c2d042ece5735d16baeade7d17d /c/src/lib/libbsp/arm/gba/irq
parente9b4f29a409d9dc192a85dbbe693aeb1fa87e43b (diff)
downloadrtems-3c7ed6b8cd505f696c9c2b6d90723094f334b348.tar.bz2
2005-07-06 Markku Puro <markku.puro@kopteri.net>
* .cvsignore, ChangeLog, Makefile.am, README, bsp_specs, configure.ac, clock/clockdrv.c, console/conio.c, console/console.c, console/defaultfont.c, include/arm_mode_bits.h, include/asm_macros.h, include/bsp.h, include/bspopts.h.in, include/conio.h, include/gba.h, include/gba_registers.h, include/tm27.h, irq/bsp_irq_asm.S, irq/bsp_irq_init.c, irq/irq.c, irq/irq.h, irq/irq_asm.S, irq/irq_init.c, start/logo.S, start/start.S, startup/bspstart.c, startup/cpu.c, startup/cpu_asm.S, startup/exit.c, startup/linkcmds, timer/timer.c: New files.
Diffstat (limited to 'c/src/lib/libbsp/arm/gba/irq')
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S179
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c38
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/irq.c161
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/irq.h196
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/irq_asm.S183
-rw-r--r--c/src/lib/libbsp/arm/gba/irq/irq_init.c71
6 files changed, 828 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
new file mode 100644
index 0000000000..3697b5e018
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S
@@ -0,0 +1,179 @@
+/**
+ * @file bsp_irq_asm.S
+ *
+ * Intererrupt handler for GameBoy Advance.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#define __asm__
+#include <asm_macros.h>
+#include <gba_registers.h>
+#include <arm_mode_bits.h>
+/* @cond INCLUDE_ASM */
+
+/**
+ * Execute interrupt handler
+ * function void ExecuteITHandler(void)
+ *
+ * Look at interrupt status register to determine source.
+ * From source, determine offset into expanded vector table
+ * and load handler address into r0.
+ * irq_vector_table is defined in linkcmds
+ *
+ */
+ .align
+/* .section .iwram */
+
+PUBLIC_ARM_FUNCTION(ExecuteITHandler)
+ ldr r1, =GBA_REG_IE_ADDR
+ ldrh r1, [r1]
+ ldr r2, =GBA_REG_IF_ADDR
+ ldrh r2, [r2]
+ and r3, r1, r2 /* only look at interrupts which are enabled */
+
+check_lcdv:
+ tst r3, #0x0001
+ beq check_lcdh
+ ldr r0, =(irq_vector_table + (4 * 0)) /* load the vector number */
+ ldr r3,=0x0001
+ b get_handler
+
+check_lcdh:
+ tst r3, #0x0002
+ beq check_lcdvc
+ ldr r0, =(irq_vector_table + (4 * 1)) /* load the vector number */
+ ldr r3,=0x0002
+ b get_handler
+
+check_lcdvc:
+ tst r3, #0x0004
+ beq check_t0
+ ldr r0, =(irq_vector_table + (4 * 2)) /* load the vector number */
+ ldr r3,=0x0004
+ b get_handler
+
+check_t0:
+ tst r3, #0x0008
+ beq check_t1
+ ldr r0, =(irq_vector_table + (4 * 3)) /* load the vector number */
+ ldr r3,=0x0008
+ b get_handler
+
+check_t1:
+ tst r3, #0x0010
+ beq check_t2
+ ldr r0, =(irq_vector_table + (4 * 4)) /* load the vector number */
+ ldr r3,=0x0010
+ b get_handler
+
+check_t2:
+ tst r3, #0x0020
+ beq check_t3
+ ldr r0, =(irq_vector_table + (4 * 5)) /* load the vector number */
+ ldr r3,=0x0020
+ b get_handler
+
+check_t3:
+ tst r3, #0x0040
+ beq check_ser
+ ldr r0, =(irq_vector_table + (4 * 6)) /* load the vector number */
+ ldr r3,=0x0040
+ b get_handler
+
+check_ser:
+ tst r3, #0x0080
+ beq check_dma0
+ ldr r0, =(irq_vector_table + (4 * 7)) /* load the vector number */
+ ldr r3,=0x0080
+ b get_handler
+
+check_dma0:
+ tst r3, #0x0100
+ beq check_dma1
+ ldr r0, =(irq_vector_table + (4 * 8)) /* load the vector number */
+ ldr r3,=0x0100
+ b get_handler
+
+check_dma1:
+ tst r3, #0x0200
+ beq check_dma2
+ ldr r0, =(irq_vector_table + (4 * 9)) /* load the vector number */
+ ldr r3,=0x0200
+ b get_handler
+
+check_dma2:
+ tst r3, #0x0400
+ beq check_dma3
+ ldr r0, =(irq_vector_table + (4 * 10)) /* load the vector number */
+ ldr r3,=0x0400
+ b get_handler
+
+check_dma3:
+ tst r3, #0x0800
+ beq check_keypad
+ ldr r0, =(irq_vector_table + (4 * 11)) /* load the vector number */
+ ldr r3,=0x0800
+ b get_handler
+
+check_keypad:
+ tst r3, #0x1000
+ beq check_gamepak
+ ldr r0, =(irq_vector_table + (4 * 12)) /* load the vector number */
+ ldr r3,=0x1000
+ b get_handler
+
+check_gamepak:
+ tst r3, #0x2000
+ beq IRQ_NoInterrupt
+ ldr r0, =(irq_vector_table + (4 * 13)) /* load the vector number */
+ ldr r3,=0x2000
+ b get_handler
+
+unknown_irq:
+ ldr r0, =(default_int_handler) /* Unknown Interrupt? */
+ ldr r3,=0x0000
+
+get_handler:
+ ldr r0, [r0] /* extract the IT handler */
+
+ ldr r2, =GBA_REG_IF_ADDR /* Clear IF */
+ strh r3, [r2]
+
+ /*
+ * re-enable interrupts at processor level
+ */
+ mrs r1, cpsr
+ bic r1, r1, #Int_Bits
+ msr cpsr, r1
+
+ stmdb sp!,{lr}
+ ldr lr, =IRQ_return /* prepare the return from handler */
+ mov pc, r0 /* EXECUTE INT HANDLER */
+
+IRQ_return:
+ ldmia sp!,{lr}
+
+ /*
+ * disable interrupts_again
+ */
+ mrs r0, cpsr
+ orr r0, r0, #Int_Bits
+ msr cpsr, r0
+
+IRQ_NoInterrupt:
+ /* return to the "main" interrupt handler */
+ mov pc, lr
+
+LABEL_END(ExecuteITHandler)
+/* @endcond */
+
diff --git a/c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c
new file mode 100644
index 0000000000..5825e6d651
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c
@@ -0,0 +1,38 @@
+/**
+ * @file bsp_irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <irq.h>
+#include <bsp.h>
+#include <gba_registers.h>
+
+
+/**
+ * @brief BSP_rtems_irq_mngt_init BSP routine initialize irq registers
+ *
+ * @param None
+ * @return None
+ */
+void BSP_rtems_irq_mngt_init(void)
+{
+ /* clear all interrupt status flags */
+ GBA_REG_IF = 0xffff;
+ /* disable all interrupts */
+ GBA_REG_IE = 0;
+ /* set master interrupt enable */
+ GBA_REG_IME = 1;
+}
diff --git a/c/src/lib/libbsp/arm/gba/irq/irq.c b/c/src/lib/libbsp/arm/gba/irq/irq.c
new file mode 100644
index 0000000000..fbf93f17cd
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/irq.c
@@ -0,0 +1,161 @@
+/**
+ * @file irq.c
+ *
+ * This file contains the implementation of the function described in irq.h.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com>
+ *
+ * Copyright (c) 2002 by Charlie Steader <charlies@poliac.com>
+ *
+ * Copyright (c) 2004 by Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <bsp.h>
+#include <irq.h>
+#include <gba_registers.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+
+
+/**
+ * @brief isValidInterrupt function check that the value given for the irq line is valid.
+ *
+ * @param irq irq number
+ * @return status code TRUE/FALSE (0/1)
+ */
+static int isValidInterrupt(int irq)
+{
+ if ( (irq < 0) || (irq > BSP_MAX_INT)) {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+
+/**
+ * @brief BSP_install_rtems_irq_handler function install rtems irq handler.
+ *
+ * @param irq irq connect data
+ * @return status code TRUE/FALSE (0/1)
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_irq_hdl *HdlTable;
+ rtems_interrupt_level level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ */
+ HdlTable = (rtems_irq_hdl *) (unsigned32)VECTOR_TABLE;
+ if (*(HdlTable + irq->name) != default_int_handler) {
+ return 0;
+ }
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * store the new handler
+ */
+ *(HdlTable + irq->name) = irq->hdl;
+
+ /*
+ * ack pending interrupt
+ */
+ GBA_REG_IF |= (1 << (irq->name));
+
+ /*
+ * initialize the control register for the concerned interrupt
+ */
+ GBA_REG_IE |= (1 << (irq->name));
+
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/**
+ * @brief BSP_remove_rtems_irq_handler function removes rtems irq handler.
+ *
+ * @param irq irq connect data
+ * @return status code TRUE/FALSE (0/1)
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ rtems_irq_hdl *HdlTable;
+ rtems_interrupt_level level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if the handler is actually connected. If not issue an error.
+ */
+ HdlTable = (rtems_irq_hdl *) (unsigned32)VECTOR_TABLE;
+ if (*(HdlTable + irq->name) != irq->hdl) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+
+ /*
+ * mask at INT controller level
+ */
+ GBA_REG_IE &= ~(1 << irq->name);
+
+ /*
+ * Disable interrupt on device
+ */
+ irq->off(irq);
+
+ /*
+ * restore the default irq value
+ */
+ *(HdlTable + irq->name) = default_int_handler;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+
+/**
+ * @brief _ThreadProcessSignalsFromIrq function check that the value given for the irq line is valid.
+ *
+ * @param cxt exeption frame
+ * @return None
+ */
+void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
+{
+ /*
+ * Process pending signals that have not already been
+ * processed by _Thread_Dispatch. This happens quite
+ * unfrequently : the ISR must have posted an action
+ * to the current running thread.
+ */
+ if ( _Thread_Do_post_task_switch_extension ||
+ _Thread_Executing->do_post_task_switch_extension )
+ {
+ _Thread_Executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+ }
+}
diff --git a/c/src/lib/libbsp/arm/gba/irq/irq.h b/c/src/lib/libbsp/arm/gba/irq/irq.h
new file mode 100644
index 0000000000..3ba5f4ebac
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/irq.h
@@ -0,0 +1,196 @@
+/**
+ * @file irq.h
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to write interrupt handlers.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef _IRQ_H_
+#define _IRQ_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Include some preprocessor value also used by assember code
+ */
+
+#define VECTOR_TABLE (&irq_vector_table[0])
+
+#include <stdint.h>
+#include <rtems.h>
+
+extern void default_int_handler();
+
+/*---------------------------------------------------------------------------*
+ * MACROS *
+ *---------------------------------------------------------------------------*/
+
+#define ENABLE_IRQ() GBA_REG_IME = 1;
+#define DISABLE_IRQ() GBA_REG_IME = 0;
+
+
+/*-------------------------------------------------------------------------+
+| Constants
++--------------------------------------------------------------------------*/
+
+typedef enum {
+ BSP_IRQ_VBLANK = 0,
+ BSP_IRQ_HBLANK = 1,
+ BSP_IRQ_VCOUNTER = 2,
+ BSP_IRQ_TIMER0 = 3,
+ BSP_IRQ_TIMER1 = 4,
+ BSP_IRQ_TIMER2 = 5,
+ BSP_IRQ_TIMER3 = 6,
+ BSP_IRQ_SERIAL = 7,
+ BSP_IRQ_DMA0 = 8,
+ BSP_IRQ_DMA1 = 9,
+ BSP_IRQ_DMA2 = 10,
+ BSP_IRQ_DMA3 = 11,
+ BSP_IRQ_KEY = 12,
+ BSP_IRQ_CART = 13,
+ BSP_IRQ_NA14 = 14,
+ BSP_IRQ_NA15 = 15,
+ BSP_MAX_INT = 16 /**< BSP_MAX_INT <= _irq_max_vector in linkcmds */
+} rtems_irq_symbolic_name;
+
+/*
+ * Type definition for RTEMS managed interrupts
+ */
+typedef unsigned char rtems_irq_level;
+typedef unsigned char rtems_irq_trigger;
+
+extern void _irq_max_vector; /**< defined in lincmds */
+extern uint32_t irq_vector_table[BSP_MAX_INT]; /**< allocated in linkcmds */
+
+
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+
+typedef void (*rtems_irq_hdl) (void);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
+
+/** irq connection data structure */
+typedef struct __rtems_irq_connect_data__ {
+ /**
+ * IRQ line
+ */
+ rtems_irq_symbolic_name name;
+ /**
+ * handler. See comment on handler properties below in function prototype.
+ */
+ rtems_irq_hdl hdl;
+ /**
+ * function for enabling interrupts at device level (ONLY!).
+ * The BSP code will automatically enable it at PIC level.
+ * RATIONALE : anyway such code has to exist in current driver code.
+ * It is usually called immediately AFTER connecting the interrupt handler.
+ * RTEMS may well need such a function when restoring normal interrupt
+ * processing after a debug session.
+ *
+ */
+ rtems_irq_enable on;
+ /**
+ * function for disabling interrupts at device level (ONLY!).
+ * The code will disable it at PIC level. RATIONALE : anyway
+ * such code has to exist for clean shutdown. It is usually called
+ * BEFORE disconnecting the interrupt. RTEMS may well need such
+ * a function when disabling normal interrupt processing for
+ * a debug session. May well be a NOP function.
+ */
+ rtems_irq_disable off;
+ /**
+ * function enabling to know what interrupt may currently occur
+ * if someone manipulates the PIC interrupt mask without care...
+ */
+ rtems_irq_is_enabled isOn;
+ /**
+ * irq priority level
+ */
+ rtems_irq_level irqLevel;
+ /**
+ * Trigger way : Rising or falling edge or High or low level
+ */
+ rtems_irq_trigger irqTrigger;
+} rtems_irq_connect_data;
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+/*
+ * ------------------------ RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+/**
+ * @brief function to initialize the interrupt for a specific BSP
+ */
+void BSP_rtems_irq_mngt_init();
+
+
+/**
+ * @brief function to connect a particular irq handler.
+ * This hanlder will NOT be called directly as the result of the corresponding interrupt.
+ * Instead, a RTEMS irq prologue will be called that will :
+ * 1) save the C scratch registers,
+ * 2) switch to a interrupt stack if the interrupt is not nested,
+ * 3) store the current i8259s' interrupt masks
+ * 4) modify them to disable the current interrupt at 8259 level (and may
+ * be others depending on software priorities)
+ * 5) aknowledge the i8259s',
+ * 6) demask the processor,
+ * 7) call the application handler
+ *
+ * As a result the hdl function provided
+ * a) can perfectly be written is C,
+ * b) may also well directly call the part of the RTEMS API that can be used
+ * from interrupt level,
+ * c) It only responsible for handling the jobs that need to be done at
+ * the device level including (aknowledging/re-enabling the interrupt at device,
+ * level, getting the data,...)
+ *
+ * When returning from the function, the following will be performed by
+ * the RTEMS irq epilogue :
+ *
+ * 1) masks the interrupts again,
+ * 2) restore the original i8259s' interrupt masks
+ * 3) switch back on the orinal stack if needed,
+ * 4) perform rescheduling when necessary,
+ * 5) restore the C scratch registers...
+ * 6) restore initial execution flow
+ *
+ */
+int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*);
+
+/**
+ * function to get the current RTEMS irq handler for ptr->name. It enables to
+ * define hanlder chain...
+ */
+int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+
+/**
+ * @brief function to get disconnect the RTEMS irq handler for ptr->name.
+ * This function checks that the value given is the current one for safety reason.
+ * The user can use the previous function to get it.
+ */
+int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IRQ_H_ */
diff --git a/c/src/lib/libbsp/arm/gba/irq/irq_asm.S b/c/src/lib/libbsp/arm/gba/irq/irq_asm.S
new file mode 100644
index 0000000000..a1bb08c313
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/irq_asm.S
@@ -0,0 +1,183 @@
+/**
+ * @file irq_asm.S
+ *
+ * This file contains the implementation of the IRQ handler.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * Copyright (c) 2002 Advent Networks, Inc.
+ * Jay Monkman <jmonkman@adventnetworks.com>
+ *
+ * Copyright (C) 2000 Canon Research France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Modified Andy Dachs <a.dachs@sstl.co.uk>
+ * Copyright (c) 2001 Surrey Satellite Technolgy Limited
+ *
+ * Modified Markku Puro <markku.puro@kopteri.net>
+ * Copyright (c) 2004
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#define __asm__
+#include <rtems/asm.h>
+#include <asm_macros.h>
+#include <arm_mode_bits.h>
+/* @cond INCLUDE_ASM */
+
+/**
+ * Interrupt handler
+ * function void _ISR_Handler(void)
+ *
+ */
+ .align
+/* .section .iwram */
+
+PUBLIC_ARM_FUNCTION(_ISR_Handler)
+ stmdb sp!, {r0, r1, r2, r3, r12} /* save regs on INT stack */
+ stmdb sp!, {lr} /* now safe to call C funcs */
+
+
+/* one nest level deeper */
+ ldr r0, =_ISR_Nest_level
+ ldr r1, [r0]
+ add r1, r1,#1
+ str r1, [r0]
+
+/* disable multitasking */
+ ldr r0, =_Thread_Dispatch_disable_level
+ ldr r1, [r0]
+ add r1, r1,#1
+ str r1, [r0]
+
+/* BSP specific function to INT handler */
+ bl ExecuteITHandler
+
+/* one less nest level */
+ ldr r0, =_ISR_Nest_level
+ ldr r1, [r0]
+ sub r1, r1,#1
+ str r1, [r0]
+
+/* unnest multitasking */
+ ldr r0, =_Thread_Dispatch_disable_level
+ ldr r1, [r0]
+ sub r1, r1,#1
+ str r1, [r0]
+
+/* check to see if we interrupted (no FIQ in GBA) */
+ mrs r0, spsr
+ and r0, r0, #Mode_Bits
+ cmp r0, #Mode_IRQ /* is it INT mode? */
+ beq exitit
+
+/* If thread dispatching is disabled, exit */
+ cmp r1, #0
+ bne exitit
+
+/* If a task switch is necessary, call scheduler */
+ ldr r0, =_Context_Switch_necessary
+ ldr r1, [r0]
+ cmp r1, #0
+
+ /* since bframe is going to clear _ISR_Signals_to_thread_executing, */
+ /* we need to load it here */
+ ldr r0, =_ISR_Signals_to_thread_executing
+ ldr r1, [r0]
+ bne bframe
+
+/* If a signals to be sent (_ISR_Signals_to_thread_executing != 0), */
+/* call scheduler */
+ cmp r1, #0
+ beq exitit
+
+/* _ISR_Signals_to_thread_executing = FALSE */
+ mov r1, #0
+ str r1, [r0]
+
+bframe:
+/* Now we need to set up the return from this ISR to be _ISR_Dispatch */
+/* To do that, we need to save the current lr_int and spsr_int on the */
+/* SVC stack */
+ mrs r0, spsr
+ ldmia sp!, {r1} /* get lr off stack */
+ stmdb sp!, {r1}
+ mrs r2, cpsr
+ bic r3, r2, #Mode_Bits
+ orr r3, r3, #ModePriv /* change to SVC mode */
+ msr cpsr_c, r3
+
+ /* now in SVC mode */
+ stmdb sp!, {r0, r1} /* put spsr_int and lr_int on SVC stack */
+ msr cpsr_c, r2 /* change back to INT mode */
+
+ /* now in INT mode */
+
+ /* replace lr with address of _ISR_Dispatch */
+ ldr lr, =_ISR_Dispatch_p_4 /* On entry to an ISR, the lr is */
+ /* the return address + 4, so */
+ /* we have to emulate that */
+ ldmia sp!, {r1} /* out with the old */
+ stmdb sp!, {lr} /* in with the new (lr) */
+
+
+ orr r0, r0, #Int_Bits
+ msr spsr, r0
+
+exitit:
+ ldmia sp!, {lr} /* restore regs from INT stack */
+ ldmia sp!, {r0, r1, r2, r3, r12} /* restore regs from INT stack */
+ subs pc, lr , #4 /* return */
+LABEL_END(_ISR_Handler)
+
+ /* on entry to _ISR_Dispatch, we're in SVC mode */
+PUBLIC_ARM_FUNCTION(_ISR_Dispatch)
+ stmdb sp!, {r0-r3, r12,lr} /* save regs on SVC stack */
+ /* (now safe to call C funcs) */
+ /* we don't save lr, since */
+ /* it's just going to get */
+ /* overwritten */
+_ISR_Dispatch_p_4:
+ bl _Thread_Dispatch
+ ldmia sp!, {r0-r3, r12, lr}
+
+ stmdb sp!, {r0-r2}
+ /* Now we have to screw with the stack */
+ mov r0, sp /* copy the SVC stack pointer */
+
+ mrs r1, cpsr
+ bic r2, r1, #Mode_Bits /* clear mode bits */
+ orr r2, r2, #(Mode_IRQ | Int_Bits) /* change to INT mode */
+ msr cpsr_c, r2 /* disable interrupts */
+
+ /* now in INT mode */
+ stmdb sp!, {r4, r5, r6} /* save temp vars on INT stack */
+ ldmia r0!, {r4, r5, r6} /* Get r0-r3 from SVC stack */
+ stmdb sp!, {r4, r5, r6} /* and save them on INT stack */
+
+ ldmia r0!, {r4, r5} /* get saved values from SVC stack */
+ /* r4=spsr, r5=lr */
+ mov lr, r5 /* restore lr_int */
+ msr spsr, r4 /* restore spsr_int */
+
+ /* switch to SVC mode, update sp, then return to INT mode */
+ msr cpsr_c, r1 /* switch to SVC mode */
+ mov sp, r0 /* update sp_svc */
+ msr cpsr_c, r2 /* switch back to INT mode */
+
+ /* pop all the registers from the stack */
+ ldmia sp!, {r0, r1, r2}
+ ldmia sp!, {r4, r5, r6}
+
+ /* Finally, we can return to the interrupted task */
+ subs pc, lr, #4
+
+LABEL_END(_ISR_Dispatch)
+/* @endcond */
+
diff --git a/c/src/lib/libbsp/arm/gba/irq/irq_init.c b/c/src/lib/libbsp/arm/gba/irq/irq_init.c
new file mode 100644
index 0000000000..c2b5c1da03
--- /dev/null
+++ b/c/src/lib/libbsp/arm/gba/irq/irq_init.c
@@ -0,0 +1,71 @@
+/**
+ * @file irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ */
+/*
+ * RTEMS GBA BSP
+ *
+ * CopyRight (C) 2000 Canon Research Centre France SA.
+ * Emmanuel Raguet, mailto:raguet@crf.canon.fr
+ *
+ * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net>
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+#include <stdint.h>
+#include <bsp.h>
+#include <irq.h>
+#include <rtems/bspIo.h>
+
+/** default int vector */
+extern void _ISR_Handler(void);
+
+/** max number of vectors, defined in linkcmds */
+extern void _irq_max_vector;
+
+/**
+ * @brief default_int_handler BSP routine is default int_handler
+ *
+ * @param None
+ * @return None
+ */
+void default_int_handler(void)
+{
+ printk("raw_idt_notify has been called \n");
+}
+
+/**
+ * @brief rtems_irq_mngt_init BSP routine initialize rtems_irq_mngt
+ *
+ * @param None
+ * @return None
+ */
+void rtems_irq_mngt_init(void)
+{
+ int i;
+ uint32_t *vectorTable;
+ rtems_interrupt_level level;
+
+ vectorTable = (uint32_t *)VECTOR_TABLE;
+
+ _CPU_ISR_Disable(level);
+
+ /* @todo Can't use exception vectors in GBA because they are already in GBA ROM BIOS */
+ /* First, connect the ISR_Handler for IRQ and FIQ interrupts */
+ /*_CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ISR_Handler, NULL);*/
+ /*_CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _ISR_Handler, NULL);*/
+
+ /* Initialize the vector table contents with default handler */
+ for (i=0 ; i < (uint32_t)&_irq_max_vector ; i++) {
+ *(vectorTable + i) = (uint32_t)(default_int_handler);
+ }
+ /* Initialize the INT at the BSP level */
+ BSP_rtems_irq_mngt_init();
+}
+