diff options
| author | Arda <[email protected]> | 2014-11-24 11:57:31 +0800 |
|---|---|---|
| committer | Arda <[email protected]> | 2014-11-24 11:57:31 +0800 |
| commit | 143d3b82244b977735649e7d7c201d2affe67460 (patch) | |
| tree | 61503d3a150cef8d8184c858efc139b146b50cf6 /libcpu | |
| parent | bc2a890ab08d163ccea323f7e719c4fdf53050cd (diff) | |
| parent | 9ecd18411fc1344e3d080d844b60c7070c3fb4d8 (diff) | |
Merge pull request #2 from RT-Thread/master
update from official source
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/arm/am335x/start_gcc.S | 24 | ||||
| -rw-r--r-- | libcpu/arm/am335x/trap.c | 18 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m0/context_gcc.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m0/context_iar.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m0/context_rvds.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m3/context_gcc.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m3/context_iar.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m3/context_rvds.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m4/context_gcc.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m4/context_iar.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m4/context_rvds.S | 8 | ||||
| -rw-r--r-- | libcpu/arm/cortex-m4/cpuport.c | 45 | ||||
| -rw-r--r-- | libcpu/mips/loongson_1b/interrupt.c | 159 | ||||
| -rw-r--r-- | libcpu/rx/context_iar.S | 132 | ||||
| -rw-r--r-- | libcpu/rx/cpuconfig.h | 7 | ||||
| -rw-r--r-- | libcpu/rx/cpuport.c | 216 |
16 files changed, 553 insertions, 120 deletions
diff --git a/libcpu/arm/am335x/start_gcc.S b/libcpu/arm/am335x/start_gcc.S index 6d9ec8be25..f80aca6223 100644 --- a/libcpu/arm/am335x/start_gcc.S +++ b/libcpu/arm/am335x/start_gcc.S @@ -33,7 +33,7 @@ .equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled .equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled -.equ UND_Stack_Size, 0x00000000 +.equ UND_Stack_Size, 0x00000200 .equ SVC_Stack_Size, 0x00000100 .equ ABT_Stack_Size, 0x00000000 .equ FIQ_Stack_Size, 0x00000000 @@ -135,7 +135,15 @@ vector_undef: sub sp, sp, #72 stmia sp, {r0 - r12} @/* Calling r0-r12 */ add r8, sp, #60 - stmdb r8, {sp, lr} @/* Calling SP, LR */ + + mrs r1, cpsr + mrs r2, spsr + orr r2,r2, #I_Bit|F_Bit + msr cpsr_c, r2 + mov r0, r0 + stmdb r8, {sp, lr} @/* Calling SP, LR */ + msr cpsr_c, r1 @/* return to Undefined Instruction mode */ + str lr, [r8, #0] @/* Save calling PC */ mrs r6, spsr str r6, [r8, #4] @/* Save CPSR */ @@ -144,6 +152,12 @@ vector_undef: bl rt_hw_trap_udef + ldmia sp, {r0 - r12} @/* Calling r0 - r2 */ + mov r0, r0 + ldr lr, [sp, #60] @/* Get PC */ + add sp, sp, #72 + movs pc, lr @/* return & move spsr_svc into cpsr */ + .align 5 .globl vector_swi vector_swi: @@ -169,6 +183,12 @@ vector_dabt: bl rt_hw_trap_dabt + ldmia sp, {r0 - r12} @/* Calling r0 - r2 */ + mov r0, r0 + ldr lr, [sp, #60] @/* Get PC */ + add sp, sp, #72 + movs pc, lr @/* return & move spsr_svc into cpsr */ + .align 5 .globl vector_resv vector_resv: diff --git a/libcpu/arm/am335x/trap.c b/libcpu/arm/am335x/trap.c index 925ec56434..89dc14255a 100644 --- a/libcpu/arm/am335x/trap.c +++ b/libcpu/arm/am335x/trap.c @@ -18,6 +18,10 @@ #include "am33xx.h" #include "interrupt.h" +#ifdef RT_USING_GDB +#include "gdb_stub.h" +#endif + /** * @addtogroup AM33XX */ @@ -55,6 +59,13 @@ void rt_hw_show_register (struct rt_hw_register *regs) */ void rt_hw_trap_udef(struct rt_hw_register *regs) { + +#ifdef RT_USING_GDB + regs->pc -= 4; //lr in undef is pc + 4 + if (gdb_undef_hook(regs)) + return; +#endif + rt_hw_show_register(regs); rt_kprintf("undefined instruction\n"); @@ -114,6 +125,13 @@ void rt_hw_trap_pabt(struct rt_hw_register *regs) */ void rt_hw_trap_dabt(struct rt_hw_register *regs) { + +#ifdef RT_USING_GDB + if (gdb_mem_fault_handler) { + regs->pc = (unsigned long)gdb_mem_fault_handler; + return; + } +#endif rt_hw_show_register(regs); rt_kprintf("data abort\n"); diff --git a/libcpu/arm/cortex-m0/context_gcc.S b/libcpu/arm/cortex-m0/context_gcc.S index 997c345179..3186a5ae9f 100644 --- a/libcpu/arm/cortex-m0/context_gcc.S +++ b/libcpu/arm/cortex-m0/context_gcc.S @@ -79,8 +79,8 @@ _reswitch: STR R1, [R0] BX LR -/* R0 --> swith from thread stack - * R1 --> swith to thread stack +/* R0 --> switch from thread stack + * R1 --> switch to thread stack * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack */ .global PendSV_Handler @@ -103,7 +103,7 @@ PendSV_Handler: LDR R0, =rt_interrupt_from_thread LDR R1, [R0] CMP R1, #0x00 - BEQ swtich_to_thread /* skip register save at the first time */ + BEQ switch_to_thread /* skip register save at the first time */ MRS R1, PSP /* get from thread stack pointer */ @@ -118,7 +118,7 @@ PendSV_Handler: MOV R6, R10 MOV R7, R11 STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */ -swtich_to_thread: +switch_to_thread: LDR R1, =rt_interrupt_to_thread LDR R1, [R1] LDR R1, [R1] /* load thread stack pointer */ diff --git a/libcpu/arm/cortex-m0/context_iar.S b/libcpu/arm/cortex-m0/context_iar.S index f1318e552d..67ea808d8c 100644 --- a/libcpu/arm/cortex-m0/context_iar.S +++ b/libcpu/arm/cortex-m0/context_iar.S @@ -81,8 +81,8 @@ _reswitch STR r1, [r0] BX LR -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack EXPORT PendSV_Handler PendSV_Handler: @@ -104,7 +104,7 @@ PendSV_Handler: LDR r0, =rt_interrupt_from_thread LDR r1, [r0] CMP r1, #0x00 - BEQ swtich_to_thread ; skip register save at the first time + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer @@ -120,7 +120,7 @@ PendSV_Handler: MOV r7, r11 STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m0/context_rvds.S b/libcpu/arm/cortex-m0/context_rvds.S index 9c2f42ac83..89ac029282 100644 --- a/libcpu/arm/cortex-m0/context_rvds.S +++ b/libcpu/arm/cortex-m0/context_rvds.S @@ -85,8 +85,8 @@ _reswitch BX LR ENDP -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack PendSV_Handler PROC EXPORT PendSV_Handler @@ -108,7 +108,7 @@ PendSV_Handler PROC LDR r0, =rt_interrupt_from_thread LDR r1, [r0] CMP r1, #0x00 - BEQ swtich_to_thread ; skip register save at the first time + BEQ switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer @@ -124,7 +124,7 @@ PendSV_Handler PROC MOV r7, r11 STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m3/context_gcc.S b/libcpu/arm/cortex-m3/context_gcc.S index 7ff810d534..ca961bbd87 100644 --- a/libcpu/arm/cortex-m3/context_gcc.S +++ b/libcpu/arm/cortex-m3/context_gcc.S @@ -80,8 +80,8 @@ _reswitch: STR R1, [R0] BX LR -/* R0 --> swith from thread stack - * R1 --> swith to thread stack +/* R0 --> switch from thread stack + * R1 --> switch to thread stack * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack */ .global PendSV_Handler @@ -102,14 +102,14 @@ PendSV_Handler: LDR R0, =rt_interrupt_from_thread LDR R1, [R0] - CBZ R1, swtich_to_thread /* skip register save at the first time */ + CBZ R1, switch_to_thread /* skip register save at the first time */ MRS R1, PSP /* get from thread stack pointer */ STMFD R1!, {R4 - R11} /* push R4 - R11 register */ LDR R0, [R0] STR R1, [R0] /* update from thread stack pointer */ -swtich_to_thread: +switch_to_thread: LDR R1, =rt_interrupt_to_thread LDR R1, [R1] LDR R1, [R1] /* load thread stack pointer */ diff --git a/libcpu/arm/cortex-m3/context_iar.S b/libcpu/arm/cortex-m3/context_iar.S index 7dc595f6c1..ad9fa0dd0f 100644 --- a/libcpu/arm/cortex-m3/context_iar.S +++ b/libcpu/arm/cortex-m3/context_iar.S @@ -81,8 +81,8 @@ _reswitch STR r1, [r0] BX LR -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack EXPORT PendSV_Handler PendSV_Handler: @@ -102,14 +102,14 @@ PendSV_Handler: LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, swtich_to_thread ; skip register save at the first time + CBZ r1, switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer STMFD r1!, {r4 - r11} ; push r4 - r11 register LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m3/context_rvds.S b/libcpu/arm/cortex-m3/context_rvds.S index 7f431cc042..c86b70e1f9 100644 --- a/libcpu/arm/cortex-m3/context_rvds.S +++ b/libcpu/arm/cortex-m3/context_rvds.S @@ -84,8 +84,8 @@ _reswitch BX LR ENDP -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack PendSV_Handler PROC EXPORT PendSV_Handler @@ -105,14 +105,14 @@ PendSV_Handler PROC LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, swtich_to_thread ; skip register save at the first time + CBZ r1, switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer STMFD r1!, {r4 - r11} ; push r4 - r11 register LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m4/context_gcc.S b/libcpu/arm/cortex-m4/context_gcc.S index 6a910355a8..908a44f847 100644 --- a/libcpu/arm/cortex-m4/context_gcc.S +++ b/libcpu/arm/cortex-m4/context_gcc.S @@ -82,8 +82,8 @@ _reswitch: STR r1, [r0] BX LR -/* r0 --> swith from thread stack - * r1 --> swith to thread stack +/* r0 --> switch from thread stack + * r1 --> switch to thread stack * psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack */ .global PendSV_Handler @@ -104,7 +104,7 @@ PendSV_Handler: LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, swtich_to_thread /* skip register save at the first time */ + CBZ r1, switch_to_thread /* skip register save at the first time */ MRS r1, psp /* get from thread stack pointer */ @@ -127,7 +127,7 @@ PendSV_Handler: LDR r0, [r0] STR r1, [r0] /* update from thread stack pointer */ -swtich_to_thread: +switch_to_thread: LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] /* load thread stack pointer */ diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index e882f36f64..8761a97052 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/libcpu/arm/cortex-m4/context_iar.S @@ -82,8 +82,8 @@ _reswitch STR r1, [r0] BX LR -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack EXPORT PendSV_Handler PendSV_Handler: @@ -103,7 +103,7 @@ PendSV_Handler: LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, swtich_to_thread ; skip register save at the first time + CBZ r1, switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer @@ -130,7 +130,7 @@ push_flag LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m4/context_rvds.S b/libcpu/arm/cortex-m4/context_rvds.S index 189ae33db1..af7461fd49 100644 --- a/libcpu/arm/cortex-m4/context_rvds.S +++ b/libcpu/arm/cortex-m4/context_rvds.S @@ -85,8 +85,8 @@ _reswitch BX LR ENDP -; r0 --> swith from thread stack -; r1 --> swith to thread stack +; r0 --> switch from thread stack +; r1 --> switch to thread stack ; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack PendSV_Handler PROC EXPORT PendSV_Handler @@ -106,7 +106,7 @@ PendSV_Handler PROC LDR r0, =rt_interrupt_from_thread LDR r1, [r0] - CBZ r1, swtich_to_thread ; skip register save at the first time + CBZ r1, switch_to_thread ; skip register save at the first time MRS r1, psp ; get from thread stack pointer @@ -129,7 +129,7 @@ PendSV_Handler PROC LDR r0, [r0] STR r1, [r0] ; update from thread stack pointer -swtich_to_thread +switch_to_thread LDR r1, =rt_interrupt_to_thread LDR r1, [r1] LDR r1, [r1] ; load thread stack pointer diff --git a/libcpu/arm/cortex-m4/cpuport.c b/libcpu/arm/cortex-m4/cpuport.c index ef5fcc8b7c..47d8473997 100644 --- a/libcpu/arm/cortex-m4/cpuport.c +++ b/libcpu/arm/cortex-m4/cpuport.c @@ -1,7 +1,7 @@ /* * File : cpuport.c * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * COPYRIGHT (C) 2006 - 2014, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -212,6 +212,9 @@ void rt_hw_hard_fault_exception(struct exception_stack_frame *exception_stack) while (1); } +/** + * shutdown CPU + */ void rt_hw_cpu_shutdown(void) { rt_kprintf("shutdown...\n"); @@ -219,3 +222,43 @@ void rt_hw_cpu_shutdown(void) RT_ASSERT(0); } +#ifdef RT_USING_CPU_FFS +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +#if defined(__CC_ARM) +__asm int __rt_ffs(int value) +{ + CMP r0, #0x00 + BEQ exit + RBIT r0, r0 + CLZ r0, r0 + ADDS r0, r0, #0x01 + +exit + BX lr +} +#elif defined(__IAR_SYSTEMS_ICC__) +int __rt_ffs(int value) +{ + if (value == 0) return value; + + __ASM("RBIT r0, r0"); + __ASM("CLZ r0, r0"); + __ASM("ADDS r0, r0, #0x01"); +} +#elif defined(__GNUC__) +int __rt_ffs(int value) +{ + return __builtin_ffs(value); +} +#endif + +#endif diff --git a/libcpu/mips/loongson_1b/interrupt.c b/libcpu/mips/loongson_1b/interrupt.c index c5b4bad038..be65da914c 100644 --- a/libcpu/mips/loongson_1b/interrupt.c +++ b/libcpu/mips/loongson_1b/interrupt.c @@ -30,7 +30,7 @@ void rt_interrupt_dispatch(void *ptreg); void rt_hw_timer_handler(); static struct ls1b_intc_regs volatile *ls1b_hw0_icregs - = (struct ls1b_intc_regs volatile *)(LS1B_INTREG_BASE); += (struct ls1b_intc_regs volatile *)(LS1B_INTREG_BASE); /** * @addtogroup Loongson LS1B @@ -40,7 +40,7 @@ static struct ls1b_intc_regs volatile *ls1b_hw0_icregs static void rt_hw_interrupt_handler(int vector, void *param) { - rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); } /** @@ -48,26 +48,26 @@ static void rt_hw_interrupt_handler(int vector, void *param) */ void rt_hw_interrupt_init(void) { - rt_int32_t idx; + rt_int32_t idx; - /* pci active low */ - ls1b_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq - /* make all interrupts level triggered */ - (ls1b_hw0_icregs+0)->int_edge = 0x0000e000; - /* mask all interrupts */ - (ls1b_hw0_icregs+0)->int_clr = 0xffffffff; + /* pci active low */ + ls1b_hw0_icregs->int_pol = -1; //must be done here 20110802 lgnq + /* make all interrupts level triggered */ + (ls1b_hw0_icregs+0)->int_edge = 0x0000e000; + /* mask all interrupts */ + (ls1b_hw0_icregs+0)->int_clr = 0xffffffff; rt_memset(irq_handle_table, 0x00, sizeof(irq_handle_table)); - for (idx = 0; idx < MAX_INTR; idx ++) - { - irq_handle_table[idx].handler = rt_hw_interrupt_handler; - } + for (idx = 0; idx < MAX_INTR; idx ++) + { + irq_handle_table[idx].handler = rt_hw_interrupt_handler; + } - /* 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; + /* 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; } /** @@ -76,8 +76,8 @@ void rt_hw_interrupt_init(void) */ void rt_hw_interrupt_mask(int vector) { - /* mask interrupt */ - (ls1b_hw0_icregs+(vector>>5))->int_en &= ~(1 << (vector&0x1f)); + /* mask interrupt */ + (ls1b_hw0_icregs+(vector>>5))->int_en &= ~(1 << (vector&0x1f)); } /** @@ -86,7 +86,7 @@ void rt_hw_interrupt_mask(int vector) */ void rt_hw_interrupt_umask(int vector) { - (ls1b_hw0_icregs+(vector>>5))->int_en |= (1 << (vector&0x1f)); + (ls1b_hw0_icregs+(vector>>5))->int_en |= (1 << (vector&0x1f)); } /** @@ -96,22 +96,19 @@ void rt_hw_interrupt_umask(int vector) * @param old_handler the old interrupt service routine */ rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, - void *param, char *name) + void *param, char *name) { rt_isr_handler_t old_handler = RT_NULL; - if (vector >= 0 && vector < MAX_INTR) - { + if (vector >= 0 && vector < MAX_INTR) + { old_handler = irq_handle_table[vector].handler; - if (handler != RT_NULL) - { #ifdef RT_USING_INTERRUPT_INFO - rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX); + rt_strncpy(irq_handle_table[vector].name, name, RT_NAME_MAX); #endif /* RT_USING_INTERRUPT_INFO */ - irq_handle_table[vector].handler = handler; - irq_handle_table[vector].param = param; - } + irq_handle_table[vector].handler = handler; + irq_handle_table[vector].param = param; } return old_handler; @@ -121,71 +118,71 @@ void rt_interrupt_dispatch(void *ptreg) { int irq; void *param; - rt_isr_handler_t irq_func; - static rt_uint32_t status = 0; - rt_uint32_t c0_status; - rt_uint32_t c0_cause; - volatile rt_uint32_t cause_im; - volatile rt_uint32_t status_im; - rt_uint32_t pending_im; + rt_isr_handler_t irq_func; + static rt_uint32_t status = 0; + rt_uint32_t c0_status; + rt_uint32_t c0_cause; + volatile rt_uint32_t cause_im; + volatile rt_uint32_t status_im; + rt_uint32_t pending_im; - /* check os timer */ - c0_status = read_c0_status(); - c0_cause = read_c0_cause(); + /* check os timer */ + c0_status = read_c0_status(); + c0_cause = read_c0_cause(); - cause_im = c0_cause & ST0_IM; - status_im = c0_status & ST0_IM; - pending_im = cause_im & status_im; + cause_im = c0_cause & ST0_IM; + status_im = c0_status & ST0_IM; + pending_im = cause_im & status_im; - if (pending_im & CAUSEF_IP7) - { - rt_hw_timer_handler(); - } + if (pending_im & CAUSEF_IP7) + { + rt_hw_timer_handler(); + } - if (pending_im & CAUSEF_IP2) - { - /* the hardware interrupt */ - status = ls1b_hw0_icregs->int_isr; - if (!status) - return; + if (pending_im & CAUSEF_IP2) + { + /* the hardware interrupt */ + status = ls1b_hw0_icregs->int_isr; + if (!status) + return; - for (irq = MAX_INTR; irq > 0; --irq) - { - if ((status & (1 << irq))) - { - status &= ~(1 << irq); + for (irq = MAX_INTR; irq > 0; --irq) + { + if ((status & (1 << irq))) + { + status &= ~(1 << irq); irq_func = irq_handle_table[irq].handler; param = irq_handle_table[irq].param; - /* do interrupt */ - (*irq_func)(irq, param); + /* do interrupt */ + irq_func(irq, param); #ifdef RT_USING_INTERRUPT_INFO irq_handle_table[irq].counter++; #endif /* RT_USING_INTERRUPT_INFO */ - /* ack interrupt */ - ls1b_hw0_icregs->int_clr |= (1 << irq); - } - } - } - else if (pending_im & CAUSEF_IP3) - { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); - } - else if (pending_im & CAUSEF_IP4) - { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); - } - else if (pending_im & CAUSEF_IP5) - { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); - } - else if (pending_im & CAUSEF_IP6) - { - rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); - } + /* ack interrupt */ + ls1b_hw0_icregs->int_clr |= (1 << irq); + } + } + } + else if (pending_im & CAUSEF_IP3) + { + rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + } + else if (pending_im & CAUSEF_IP4) + { + rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + } + else if (pending_im & CAUSEF_IP5) + { + rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + } + else if (pending_im & CAUSEF_IP6) + { + rt_kprintf("%s %d\r\n", __FUNCTION__, __LINE__); + } } /*@}*/ diff --git a/libcpu/rx/context_iar.S b/libcpu/rx/context_iar.S new file mode 100644 index 0000000000..143ae00315 --- /dev/null +++ b/libcpu/rx/context_iar.S @@ -0,0 +1,132 @@ +#include "cpuconfig.h" + +//#include "iorx62n.h" + EXTERN _rt_thread_switch_interrupt_flag + EXTERN _rt_interrupt_from_thread + EXTERN _rt_interrupt_to_thread + EXTERN _rt_hw_hard_fault_exception + EXTERN _rt_hw_cpu_shutdown + + /*PUBLIC _Interrupt_SWINT*/ + PUBLIC ___interrupt_27 + PUBLIC ___interrupt_0 + RSEG CODE:CODE(4) + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ + PUBLIC _rt_hw_interrupt_disable +_rt_hw_interrupt_disable: + MVTIPL #MAX_SYSCALL_INTERRUPT_PRIORITY + RTS + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ + PUBLIC _rt_hw_interrupt_enable +_rt_hw_interrupt_enable: + MVTIPL #KERNEL_INTERRUPT_PRIORITY + RTS + +; r0 --> swith from thread stack +; r1 --> swith to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack +___interrupt_27: + +/* enable interrupt because enter the interrupt,it will be clear */ + SETPSW I + MVTIPL #MAX_SYSCALL_INTERRUPT_PRIORITY + PUSH.L R15 + +/* justage if it should switch thread*/ + MOV.L #_rt_thread_switch_interrupt_flag, R15 + MOV.L [ R15 ], R15 + CMP #0, R15 + BEQ notask_exit +/* clean the flag*/ + MOV.L #_rt_thread_switch_interrupt_flag, R15 + MOV.L #0, [ R15 ] + +/* justage if it should save the register*/ + MOV.L #_rt_interrupt_from_thread, R15 + MOV.L [ R15 ], R15 + CMP #0, R15 + BEQ need_modify_isp + /*save register*/ + MVFC USP, R15 + SUB #12, R15 + MVTC R15, USP + MOV.L [ R0 ], [ R15 ] ;PSW + MOV.L 4[ R0 ], 4[ R15 ];PC + MOV.L 8[ R0 ], 8[ R15 ] ;R15 + ADD #12, R0 + SETPSW U + PUSHM R1-R14 + MVFC FPSW, R15 + PUSH.L R15 + MVFACHI R15 + PUSH.L R15 + MVFACMI R15 ; Middle order word. + SHLL #16, R15 ; Shifted left as it is restored to the low orde r w + PUSH.L R15 + /*save thread stack pointer and switch to new thread*/ + MOV.L #_rt_interrupt_from_thread, R15 + MOV.L [ R15 ], R15 + MOV.L R0, [ R15 ] + BRA swtich_to_thread +need_modify_isp: + MVFC ISP, R15 + ADD #12, R15 + MVTC R15, ISP +swtich_to_thread: + SETPSW U + MOV.L #_rt_interrupt_to_thread, R15 + MOV.L [ R15 ], R15 + MOV.L [ R15 ], R0 + POP R15 + MVTACLO R15 + POP R15 + MVTACHI R15 + POP R15 + MVTC R15, FPSW + POPM R1-R15 + BRA pendsv_exit +notask_exit: + POP R15 +pendsv_exit: + + MVTIPL #KERNEL_INTERRUPT_PRIORITY + RTE + NOP + NOP +/*exception interrupt*/ +___interrupt_0: + PUSH.L R15 + /*save the register for infomation*/ + MVFC USP, R15 + SUB #12, R15 + MVTC R15, USP + MOV.L [ R0 ], [ R15 ] ;PSW + MOV.L 4[ R0 ], 4[ R15 ];PC + MOV.L 8[ R0 ], 8[ R15 ] ;R15 + ADD #12, R0 + SETPSW U + PUSHM R1-R14 + MVFC FPSW, R15 + PUSH.L R15 + MVFACHI R15 + PUSH.L R15 + MVFACMI R15 ; Middle order word. + SHLL #16, R15 ; Shifted left as it is restored to the low orde r w + PUSH.L R15 + /*save the exception infomation add R1 as a parameter of + * function rt_hw_hard_fault_exception + */ + MOV.L R0, R1 + BRA _rt_hw_hard_fault_exception + BRA _rt_hw_cpu_shutdown + RTE + NOP + NOP + END + diff --git a/libcpu/rx/cpuconfig.h b/libcpu/rx/cpuconfig.h new file mode 100644 index 0000000000..8b0fd37ce8 --- /dev/null +++ b/libcpu/rx/cpuconfig.h @@ -0,0 +1,7 @@ +#ifndef __CPU_CONFIG_H__ +#define __CPU_CONFIG_H__ + +#define MAX_SYSCALL_INTERRUPT_PRIORITY 10 +#define KERNEL_INTERRUPT_PRIORITY 1 + +#endif diff --git a/libcpu/rx/cpuport.c b/libcpu/rx/cpuport.c new file mode 100644 index 0000000000..e8a75c629e --- /dev/null +++ b/libcpu/rx/cpuport.c @@ -0,0 +1,216 @@ +/* + * File : cpuport.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 - 2011, 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 + * 2011-02-23 Bernard the first version + * 2012-03-03 xuzhenglim modify for rx62N + */ +#include <rthw.h> +#include <rtthread.h> + +#include "cpuconfig.h" + +#include "machine.h" +#include "iorx62n.h" + +#define ENTER_INTERRUPT() ICU.SWINTR.BIT.SWINT = 1; + +extern volatile rt_uint8_t rt_interrupt_nest; + + +/* switch flag on interrupt and thread pointer to save switch record */ +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + + +/* stack frame*/ +struct stack_frame +{ + rt_uint32_t ACCLO; + rt_uint32_t ACCHI; + rt_uint32_t FPSW; + rt_uint32_t R1; + rt_uint32_t R2; + rt_uint32_t R3; + rt_uint32_t R4; + rt_uint32_t R5; + rt_uint32_t R6; + rt_uint32_t R7; + rt_uint32_t R8; + rt_uint32_t R9; + rt_uint32_t R10; + rt_uint32_t R11; + rt_uint32_t R12; + rt_uint32_t R13; + rt_uint32_t R14; + rt_uint32_t R15; + //there is not R0 register,it is special for stack pointer + rt_uint32_t PC; + rt_uint32_t PSW; +}; + +/** + * Initilial the threah stack. + * + * @author LXZ (2014/11/8) + * + * @param void* tentry + * @param void* parameter + * @param rt_uint8_t* stack_addr + * @param void* texit + * + * @return rt_uint8_t* + */ +rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, + rt_uint8_t *stack_addr, void *texit) +{ + unsigned long *stk; + struct stack_frame *stack_frame; + unsigned long i; + + stk = (unsigned long *)stack_addr; + *(stk) = (unsigned long)texit; + stack_frame = (struct stack_frame *)(stack_addr - sizeof(struct stack_frame)) ; + + //Initilial all register + for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) + { + ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; + } + + stack_frame->PSW = (unsigned long)0x00030000 ; /* psw */ + stack_frame->PC = (unsigned long)tentry; /* thread entery*/ + stack_frame->R1 = (unsigned long )parameter; /* r1 : parameter */ + stack_frame->FPSW = 0x00000100; /* fpsw */ + + return(rt_uint8_t *)stack_frame; +} + +#ifdef RT_USING_FINSH +extern void list_thread(void); +#endif +extern rt_thread_t rt_current_thread; +/** + * deal exception + * + * @author LXZ (2014/11/8) + * + * @param struct stack_frame* exception_contex + */ +void rt_hw_hard_fault_exception(struct stack_frame* exception_contex) +{ + if (exception_contex != RT_NULL) { + rt_kprintf("psw: 0x%08x\n", exception_contex->PSW); + rt_kprintf("pc: 0x%08x\n", exception_contex->PC); + rt_kprintf("r0: 0x%08x\n", exception_contex->R1); + rt_kprintf("r0: 0x%08x\n", exception_contex->R2); + rt_kprintf("r0: 0x%08x\n", exception_contex->R3); + rt_kprintf("r0: 0x%08x\n", exception_contex->R4); + rt_kprintf("r0: 0x%08x\n", exception_contex->R5); + rt_kprintf("r0: 0x%08x\n", exception_contex->R6); + rt_kprintf("r0: 0x%08x\n", exception_contex->R7); + rt_kprintf("r0: 0x%08x\n", exception_contex->R8); + rt_kprintf("r0: 0x%08x\n", exception_contex->R9); + rt_kprintf("r0: 0x%08x\n", exception_contex->R10); + rt_kprintf("r0: 0x%08x\n", exception_contex->R11); + rt_kprintf("r0: 0x%08x\n", exception_contex->R12); + rt_kprintf("r0: 0x%08x\n", exception_contex->R13); + rt_kprintf("r0: 0x%08x\n", exception_contex->R14); + rt_kprintf("r0: 0x%08x\n", exception_contex->R15); + rt_kprintf("fpsw: 0x%08x\n", exception_contex->FPSW); + rt_kprintf("acchi: 0x%08x\n", exception_contex->ACCHI); + rt_kprintf("acclo: 0x%08x\n", exception_contex->ACCLO); + } + rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); + #ifdef RT_USING_FINSH + list_thread(); + #endif + while (1); + +} + + +/** + * switch thread in interrupt + * + * @author LXZ (2014/11/8) + * + * @param rt_uint32_t from + * @param rt_uint32_t to + */ +void rt_hw_context_switch(rt_uint32_t from, rt_uint32_t to) +{ + if (rt_thread_switch_interrupt_flag == 0) + { + rt_thread_switch_interrupt_flag = 1; + rt_interrupt_from_thread = from; + } + + rt_interrupt_to_thread = to; + ENTER_INTERRUPT(); +} +/** + * swithc thread out the interrupt + * + * @author LXZ (2014/11/8) + * + * @param rt_uint32_t from + * @param rt_uint32_t to + */ +void rt_hw_context_switch_interrupt(rt_uint32_t from, rt_uint32_t to) +{ + if (rt_thread_switch_interrupt_flag == 0) + { + rt_thread_switch_interrupt_flag = 1; + rt_interrupt_from_thread = from; + } + + rt_interrupt_to_thread = to; + ENTER_INTERRUPT(); +} + +/** + * shut down the chip + * + * @author LXZ (2014/11/8) + */ +void rt_hw_cpu_shutdown(void) +{ + rt_kprintf("shutdown...\n"); + + RT_ASSERT(0); +} +/** + * switch to the first thread,it just call one time + * + * @author LXZ (2014/11/8) + * + * @param rt_uint32_t to + */ +void rt_hw_context_switch_to(rt_uint32_t to) +{ + + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = to; + rt_thread_switch_interrupt_flag = 1; + /* enable interrupt*/ + _IEN( _ICU_SWINT ) = 1; + + /*clear the interrupt flag*/ + _IR( _ICU_SWINT ) = 0; + _IPR( _ICU_SWINT ) = MAX_SYSCALL_INTERRUPT_PRIORITY + 1; + + /*touch the software interrupt*/ + ENTER_INTERRUPT(); + /*wait for first thread start up*/ + while(1); +} + |
