From 3c7ed6b8cd505f696c9c2b6d90723094f334b348 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 6 Jul 2005 18:46:04 +0000 Subject: 2005-07-06 Markku Puro * .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. --- c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S | 179 +++++++++++++++++++++++++ c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c | 38 ++++++ c/src/lib/libbsp/arm/gba/irq/irq.c | 161 +++++++++++++++++++++++ c/src/lib/libbsp/arm/gba/irq/irq.h | 196 ++++++++++++++++++++++++++++ c/src/lib/libbsp/arm/gba/irq/irq_asm.S | 183 ++++++++++++++++++++++++++ c/src/lib/libbsp/arm/gba/irq/irq_init.c | 71 ++++++++++ 6 files changed, 828 insertions(+) create mode 100644 c/src/lib/libbsp/arm/gba/irq/bsp_irq_asm.S create mode 100644 c/src/lib/libbsp/arm/gba/irq/bsp_irq_init.c create mode 100644 c/src/lib/libbsp/arm/gba/irq/irq.c create mode 100644 c/src/lib/libbsp/arm/gba/irq/irq.h create mode 100644 c/src/lib/libbsp/arm/gba/irq/irq_asm.S create mode 100644 c/src/lib/libbsp/arm/gba/irq/irq_init.c (limited to 'c/src/lib/libbsp/arm/gba/irq') 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 + * + * 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 +#include +#include +/* @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 + * + * 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 +#include +#include + + +/** + * @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 + * + * Copyright (c) 2002 by Charlie Steader + * + * Copyright (c) 2004 by Markku Puro + * + * 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 +#include +#include +#include +#include + + +/** + * @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 + * + * 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 +#include + +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 + * + * Copyright (C) 2000 Canon Research France SA. + * Emmanuel Raguet, mailto:raguet@crf.canon.fr + * + * Modified Andy Dachs + * Copyright (c) 2001 Surrey Satellite Technolgy Limited + * + * Modified Markku Puro + * 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 +#include +#include +/* @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 + * + * 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 +#include +#include +#include + +/** 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(); +} + -- cgit v1.2.3