summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2013-06-03 06:38:51 +0800
committerBernard Xiong <[email protected]>2013-06-03 06:38:51 +0800
commit3c04d0b0a06f6984829d682dbef4de280a139480 (patch)
tree885fbea1d200aabf499869fe69cd36526c86339f /libcpu
parent84da2a4dcc0a00ee02a83870990a3a27e5c1c344 (diff)
parent8238f850369b82843e6d2cef050a412d9218436c (diff)
Merge branch 'master' of https://github.com/RT-Thread/rt-thread
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/arm/cortex-r4/RM48x50.h39
-rw-r--r--libcpu/arm/cortex-r4/context_ccs.asm254
-rw-r--r--libcpu/arm/cortex-r4/cpu.c42
-rw-r--r--libcpu/arm/cortex-r4/interrupt.c106
-rw-r--r--libcpu/arm/cortex-r4/stack.c85
-rw-r--r--libcpu/arm/cortex-r4/trap.c150
6 files changed, 676 insertions, 0 deletions
diff --git a/libcpu/arm/cortex-r4/RM48x50.h b/libcpu/arm/cortex-r4/RM48x50.h
new file mode 100644
index 0000000000..9f4bcc976f
--- /dev/null
+++ b/libcpu/arm/cortex-r4/RM48x50.h
@@ -0,0 +1,39 @@
+#ifndef RM48X50_H
+#define RM48X50_H
+
+#include <system.h>
+#include <sys_vim.h>
+
+#define USERMODE 0x10
+#define FIQMODE 0x11
+#define IRQMODE 0x12
+#define SVCMODE 0x13
+#define ABORTMODE 0x17
+#define UNDEFMODE 0x1b
+#define MODEMASK 0x1f
+#define NOINT 0xc0
+
+struct rt_hw_register
+{
+ unsigned long r0;
+ unsigned long r1;
+ unsigned long r2;
+ unsigned long r3;
+ unsigned long r4;
+ unsigned long r5;
+ unsigned long r6;
+ unsigned long r7;
+ unsigned long r8;
+ unsigned long r9;
+ unsigned long r10;
+ unsigned long fp;
+ unsigned long ip;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+ unsigned long cpsr;
+ unsigned long ORIG_r0;
+};
+
+#endif /* end of include guard: RM48X50_H */
+
diff --git a/libcpu/arm/cortex-r4/context_ccs.asm b/libcpu/arm/cortex-r4/context_ccs.asm
new file mode 100644
index 0000000000..dc4113f5e4
--- /dev/null
+++ b/libcpu/arm/cortex-r4/context_ccs.asm
@@ -0,0 +1,254 @@
+;/*
+; * File : context_ccs.asm
+; * This file is part of RT-Thread RTOS
+; * COPYRIGHT (C) 2006, RT-Thread Development Team
+; *
+; * The license and distribution terms for this file may be
+; * found in the file LICENSE in this distribution or at
+; * http://www.rt-thread.org/license/LICENSE
+; *
+; * Change Logs:
+; * Date Author Notes
+; * 2009-01-20 Bernard first version
+; * 2011-07-22 Bernard added thumb mode porting
+; * 2013-05-24 Grissiom port to CCS
+; * 2013-05-26 Grissiom optimize for ARMv7
+; */
+
+ .text
+ .arm
+ .ref rt_thread_switch_interrupt_flag
+ .ref rt_interrupt_from_thread
+ .ref rt_interrupt_to_thread
+ .ref rt_interrupt_enter
+ .ref rt_interrupt_leave
+ .ref rt_hw_trap_irq
+
+;/*
+; * rt_base_t rt_hw_interrupt_disable();
+; */
+ .def rt_hw_interrupt_disable
+rt_hw_interrupt_disable
+ MRS r0, cpsr
+ CPSID IF
+ BX lr
+
+;/*
+; * void rt_hw_interrupt_enable(rt_base_t level);
+; */
+ .def rt_hw_interrupt_enable
+rt_hw_interrupt_enable
+ MSR cpsr_c, r0
+ BX lr
+
+;/*
+; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+; * r0 --> from
+; * r1 --> to
+; */
+ .def rt_hw_context_switch
+rt_hw_context_switch
+ STMDB sp!, {lr} ; push pc (lr should be pushed in place of PC)
+ STMDB sp!, {r0-r12, lr} ; push lr & register file
+
+ MRS r4, cpsr
+ TST lr, #0x01
+ ORRNE r4, r4, #0x20 ; it's thumb code
+
+ STMDB sp!, {r4} ; push cpsr
+
+ .if (__TI_VFP_SUPPORT__)
+ VMRS r4, fpexc
+ TST r4, #0x40000000
+ BEQ __no_vfp_frame1
+ VSTMDB sp!, {d0-d15}
+ VMRS r5, fpscr
+ ; TODO: add support for Common VFPv3.
+ ; Save registers like FPINST, FPINST2
+ STMDB sp!, {r5}
+__no_vfp_frame1
+ STMDB sp!, {r4}
+ .endif
+
+ STR sp, [r0] ; store sp in preempted tasks TCB
+ LDR sp, [r1] ; get new task stack pointer
+
+ .if (__TI_VFP_SUPPORT__)
+ LDMIA sp!, {r0} ; get fpexc
+ VMSR fpexc, r0 ; restore fpexc
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame2
+ LDMIA sp!, {r1} ; get fpscr
+ VMSR fpscr, r1
+ VLDMIA sp!, {d0-d15}
+__no_vfp_frame2
+ .endif
+
+ LDMIA sp!, {r4} ; pop new task cpsr to spsr
+ MSR spsr_cxsf, r4
+
+ LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+
+;/*
+; * void rt_hw_context_switch_to(rt_uint32 to);
+; * r0 --> to
+; */
+ .def rt_hw_context_switch_to
+rt_hw_context_switch_to
+ LDR sp, [r0] ; get new task stack pointer
+
+ .if (__TI_VFP_SUPPORT__)
+ LDMIA sp!, {r0} ; get fpexc
+ VMSR fpexc, r0
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_to
+ LDMIA sp!, {r1} ; get fpscr
+ VMSR fpscr, r1
+ VLDMIA sp!, {d0-d15}
+__no_vfp_frame_to
+ .endif
+
+ LDMIA sp!, {r4} ; pop new task cpsr to spsr
+ MSR spsr_cxsf, r4
+
+ LDMIA sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc, copy spsr to cpsr
+
+;/*
+; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+; */
+
+ .def rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt
+ LDR r2, pintflag
+ LDR r3, [r2]
+ CMP r3, #1
+ BEQ _reswitch
+ MOV r3, #1 ; set rt_thread_switch_interrupt_flag to 1
+ STR r3, [r2]
+ LDR r2, pfromthread ; set rt_interrupt_from_thread
+ STR r0, [r2]
+_reswitch
+ LDR r2, ptothread ; set rt_interrupt_to_thread
+ STR r1, [r2]
+ BX lr
+
+ .def IRQ_Handler
+IRQ_Handler
+ STMDB sp!, {r0-r12,lr}
+
+ .if (__TI_VFP_SUPPORT__)
+ VMRS r0, fpexc
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_str_irq
+ VSTMDB sp!, {d0-d15}
+ VMRS r1, fpscr
+ ; TODO: add support for Common VFPv3.
+ ; Save registers like FPINST, FPINST2
+ STMDB sp!, {r1}
+__no_vfp_frame_str_irq
+ STMDB sp!, {r0}
+ .endif
+
+ BL rt_interrupt_enter
+ BL rt_hw_trap_irq
+ BL rt_interrupt_leave
+
+ ; if rt_thread_switch_interrupt_flag set, jump to
+ ; rt_hw_context_switch_interrupt_do and don't return
+ LDR r0, pintflag
+ LDR r1, [r0]
+ CMP r1, #1
+ BEQ rt_hw_context_switch_interrupt_do
+
+ .if (__TI_VFP_SUPPORT__)
+ LDMIA sp!, {r0} ; get fpexc
+ VMSR fpexc, r0
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_ldr_irq
+ LDMIA sp!, {r1} ; get fpscr
+ VMSR fpscr, r1
+ VLDMIA sp!, {d0-d15}
+__no_vfp_frame_ldr_irq
+ .endif
+
+ LDMIA sp!, {r0-r12,lr}
+ SUBS pc, lr, #4
+
+; /*
+; * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+; */
+ .def rt_hw_context_switch_interrupt_do
+rt_hw_context_switch_interrupt_do
+ MOV r1, #0 ; clear flag
+ STR r1, [r0]
+
+ .if (__TI_VFP_SUPPORT__)
+ LDMIA sp!, {r0} ; get fpexc
+ VMSR fpexc, r0
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_do1
+ LDMIA sp!, {r1} ; get fpscr
+ VMSR fpscr, r1
+ VLDMIA sp!, {d0-d15}
+__no_vfp_frame_do1
+ .endif
+
+ LDMIA sp!, {r0-r12,lr} ; reload saved registers
+ STMDB sp, {r0-r3} ; save r0-r3. We will restore r0-r3 in the SVC
+ ; mode so there is no need to update SP.
+ SUB r1, sp, #16 ; save the right SP value in r1, so we could restore r0-r3.
+ SUB r2, lr, #4 ; save old task's pc to r2
+
+ MRS r3, spsr ; get cpsr of interrupt thread
+
+ ; switch to SVC mode and no interrupt
+ CPSID IF, #0x13
+
+ STMDB sp!, {r2} ; push old task's pc
+ STMDB sp!, {r4-r12,lr} ; push old task's lr,r12-r4
+ LDMIA r1!, {r4-r7} ; restore r0-r3 of the interrupted thread
+ STMDB sp!, {r4-r7} ; push old task's r3-r0. We don't need to push/pop them to
+ ; r0-r3 because we just want to transfer the data and don't
+ ; use them here.
+ STMDB sp!, {r3} ; push old task's cpsr
+
+ .if (__TI_VFP_SUPPORT__)
+ VMRS r0, fpexc
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_do2
+ VSTMDB sp!, {d0-d15}
+ VMRS r1, fpscr
+ ; TODO: add support for Common VFPv3.
+ ; Save registers like FPINST, FPINST2
+ STMDB sp!, {r1}
+__no_vfp_frame_do2
+ STMDB sp!, {r0}
+ .endif
+
+ LDR r4, pfromthread
+ LDR r5, [r4]
+ STR sp, [r5] ; store sp in preempted tasks's TCB
+
+ LDR r6, ptothread
+ LDR r6, [r6]
+ LDR sp, [r6] ; get new task's stack pointer
+
+ .if (__TI_VFP_SUPPORT__)
+ LDMIA sp!, {r0} ; get fpexc
+ VMSR fpexc, r0
+ TST r0, #0x40000000
+ BEQ __no_vfp_frame_do3
+ LDMIA sp!, {r1} ; get fpscr
+ VMSR fpscr, r1
+ VLDMIA sp!, {d0-d15}
+__no_vfp_frame_do3
+ .endif
+
+ LDMIA sp!, {r4} ; pop new task's cpsr to spsr
+ MSR spsr_cxsf, r4
+
+ LDMIA sp!, {r0-r12,lr,pc}^ ; pop new task's r0-r12,lr & pc, copy spsr to cpsr
+
+pintflag .word rt_thread_switch_interrupt_flag
+pfromthread .word rt_interrupt_from_thread
+ptothread .word rt_interrupt_to_thread
diff --git a/libcpu/arm/cortex-r4/cpu.c b/libcpu/arm/cortex-r4/cpu.c
new file mode 100644
index 0000000000..569f7d0c29
--- /dev/null
+++ b/libcpu/arm/cortex-r4/cpu.c
@@ -0,0 +1,42 @@
+/*
+ * File : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ * 2013-05-24 Grissiom port to RM48x50
+ */
+
+#include <rtthread.h>
+
+/**
+ * @addtogroup RM48x50
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+ rt_kprintf("shutdown...\n");
+
+ while (1);
+}
+
+/*@}*/
diff --git a/libcpu/arm/cortex-r4/interrupt.c b/libcpu/arm/cortex-r4/interrupt.c
new file mode 100644
index 0000000000..8d0a977db9
--- /dev/null
+++ b/libcpu/arm/cortex-r4/interrupt.c
@@ -0,0 +1,106 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ * 2013-03-29 aozima Modify the interrupt interface implementations.
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include "RM48x50.h"
+
+#define MAX_HANDLERS 96
+
+/* exception and interrupt handler table */
+struct rt_irq_desc irq_desc[MAX_HANDLERS];
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+/**
+ * @addtogroup RM48x50
+ */
+
+/*@{*/
+
+static void rt_hw_int_not_handle(int vector, void *param)
+{
+ rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+#define vimRAM (0xFFF82000U)
+
+void rt_hw_interrupt_init(void)
+{
+ register int i;
+
+ rt_uint32_t *vect_addr;
+
+ /* the initialization is done in sys_startup.c */
+
+ /* init exceptions table */
+ rt_memset(irq_desc, 0x00, sizeof(irq_desc));
+ for(i=0; i < MAX_HANDLERS; i++)
+ {
+ irq_desc[i].handler = rt_hw_int_not_handle;
+
+ vect_addr = (rt_uint32_t *)(vimRAM + i*4);
+ *vect_addr = (rt_uint32_t)&irq_desc[i];
+ }
+
+ /* init interrupt nest, and context in thread sp */
+ rt_interrupt_nest = 0;
+ rt_interrupt_from_thread = 0;
+ rt_interrupt_to_thread = 0;
+ rt_thread_switch_interrupt_flag = 0;
+}
+
+void rt_hw_interrupt_mask(int vector)
+{
+ vimDisableInterrupt(vector);
+}
+
+void rt_hw_interrupt_umask(int vector)
+{
+ vimEnableInterrupt(vector, SYS_IRQ);
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the parameter for interrupt service routine
+ * @name unused.
+ *
+ * @return the old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+ void *param, char *name)
+{
+ rt_isr_handler_t old_handler = RT_NULL;
+
+ if(vector >= 0 && vector < MAX_HANDLERS)
+ {
+ old_handler = irq_desc[vector].handler;
+ if (handler != RT_NULL)
+ {
+ irq_desc[vector].handler = handler;
+ irq_desc[vector].param = param;
+ }
+ }
+
+ return old_handler;
+}
+
+/*@}*/
diff --git a/libcpu/arm/cortex-r4/stack.c b/libcpu/arm/cortex-r4/stack.c
new file mode 100644
index 0000000000..02dc84e6f1
--- /dev/null
+++ b/libcpu/arm/cortex-r4/stack.c
@@ -0,0 +1,85 @@
+/*
+ * File : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ * 2013-05-24 Grissiom port to RM48x50
+ */
+#include <rtthread.h>
+#include "RM48x50.h"
+/**
+ * @addtogroup RM48x50
+ */
+/*@{*/
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+ rt_uint8_t *stack_addr, void *texit)
+{
+ unsigned long *stk;
+
+ stk = (unsigned long*)stack_addr;
+ *( stk) = (unsigned long) tentry; /* entry point */
+ *(--stk) = (unsigned long) texit; /* lr */
+ *(--stk) = 0; /* r12 */
+ *(--stk) = 0; /* r11 */
+ *(--stk) = 0; /* r10 */
+ *(--stk) = 0; /* r9 */
+ *(--stk) = 0; /* r8 */
+ *(--stk) = 0; /* r7 */
+ *(--stk) = 0; /* r6 */
+ *(--stk) = 0; /* r5 */
+ *(--stk) = 0; /* r4 */
+ *(--stk) = 0; /* r3 */
+ *(--stk) = 0; /* r2 */
+ *(--stk) = 0; /* r1 */
+ *(--stk) = (unsigned long)parameter; /* r0 : argument */
+
+ /* cpsr */
+ if ((rt_uint32_t)tentry & 0x01)
+ *(--stk) = SVCMODE | 0x20; /* thumb mode */
+ else
+ *(--stk) = SVCMODE; /* arm mode */
+
+#ifdef __TI_VFP_SUPPORT__
+#ifndef RT_VFP_LAZY_STACKING
+ {
+ #define VFP_DATA_NR 32
+ int i;
+
+ for (i = 0; i < VFP_DATA_NR; i++)
+ {
+ *(--stk) = 0;
+ }
+ /* FPSCR TODO: do we need to set the values other than 0? */
+ *(--stk) = 0;
+ /* FPEXC. Enable the FVP if no lazy stacking. */
+ *(--stk) = 0x40000000;
+ }
+#else
+ /* FPEXC. Disable the FVP by default. */
+ *(--stk) = 0x00000000;
+#endif
+#endif
+
+ /* return task's current stack address */
+ return (rt_uint8_t *)stk;
+}
+
+/*@}*/
diff --git a/libcpu/arm/cortex-r4/trap.c b/libcpu/arm/cortex-r4/trap.c
new file mode 100644
index 0000000000..d77f9734da
--- /dev/null
+++ b/libcpu/arm/cortex-r4/trap.c
@@ -0,0 +1,150 @@
+/*
+ * File : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://openlab.rt-thread.com/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2008-12-11 XuXinming first version
+ * 2013-05-24 Grissiom port to RM48x50
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include "RM48x50.h"
+//#define BSP_INT_DEBUG
+
+/**
+ * @addtogroup RM48x50
+ */
+/*@{*/
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+ rt_kprintf("Execption:\n");
+ rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+ rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+ rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+ rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+ rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+ rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+ rt_kprintf("undefined instruction\n");
+ rt_hw_show_register(regs);
+ if (rt_thread_self() != RT_NULL)
+ rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+ rt_kprintf("software interrupt\n");
+ rt_hw_show_register(regs);
+ if (rt_thread_self() != RT_NULL)
+ rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+ rt_kprintf("prefetch abort\n");
+ rt_hw_show_register(regs);
+ if (rt_thread_self() != RT_NULL)
+ rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+ rt_kprintf("Data Abort ");
+ rt_hw_show_register(regs);
+ if (rt_thread_self() != RT_NULL)
+ rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+ rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+ rt_kprintf("not used\n");
+ rt_hw_show_register(regs);
+ if (rt_thread_self() != RT_NULL)
+ rt_kprintf("Current Thread: %s\n", rt_thread_self()->name);
+ rt_hw_cpu_shutdown();
+}
+
+/*
+ *#pragma CODE_STATE(rt_hw_trap_irq, 32)
+ *#pragma INTERRUPT(rt_hw_trap_irq, IRQ)
+ */
+extern rt_isr_handler_t isr_table[];
+void rt_hw_trap_irq(void)
+{
+ int irqno;
+ struct rt_irq_desc* irq;
+ extern struct rt_irq_desc irq_desc[];
+
+ irq = (struct rt_irq_desc*) vimREG->IRQVECREG;
+ irqno = ((rt_uint32_t) irq - (rt_uint32_t) &irq_desc[0])/sizeof(struct rt_irq_desc);
+
+ /* invoke isr */
+ irq->handler(irqno, irq->param);
+}
+
+void rt_hw_trap_fiq(void)
+{
+ rt_kprintf("fast interrupt request\n");
+}
+
+/*@}*/