update cortex-m3 libcpu

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1776 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
wuyangyong 2011-10-28 13:19:30 +00:00
parent b1531d316d
commit 8c54e1c47b
2 changed files with 294 additions and 106 deletions

View File

@ -0,0 +1,188 @@
;/*
; * File : context_rvds.S
; * This file is part of RT-Thread RTOS
; * COPYRIGHT (C) 2009, 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-17 Bernard first version
; */
;/**
; * @addtogroup CORTEX-M3
; */
;/*@{*/
NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register
NVIC_SYSPRI2 EQU 0xE000ED20 ; system priority register (2)
NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest)
NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception
AREA |.text|, CODE, READONLY, ALIGN=2
THUMB
REQUIRE8
PRESERVE8
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK
CPSID I
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0
BX LR
ENDP
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch_interrupt
EXPORT rt_hw_context_switch_interrupt
rt_hw_context_switch PROC
EXPORT rt_hw_context_switch
; set rt_thread_switch_interrupt_flag to 1
LDR r2, =rt_thread_switch_interrupt_flag
LDR r3, [r2]
CMP r3, #1
BEQ _reswitch
MOV r3, #1
STR r3, [r2]
LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR r0, [r2]
_reswitch
LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR r1, [r2]
LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch)
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
BX LR
ENDP
; r0 --> swith from thread stack
; r1 --> swith to thread stack
; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack
PendSV_Handler PROC
EXPORT PendSV_Handler
; disable interrupt to protect context switch
MRS r2, PRIMASK
CPSID I
; get rt_thread_switch_interrupt_flag
LDR r0, =rt_thread_switch_interrupt_flag
LDR r1, [r0]
CBZ r1, pendsv_exit ; pendsv already handled
; clear rt_thread_switch_interrupt_flag to 0
MOV r1, #0x00
STR r1, [r0]
LDR r0, =rt_interrupt_from_thread
LDR r1, [r0]
CBZ r1, swtich_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
LDR r1, =rt_interrupt_to_thread
LDR r1, [r1]
LDR r1, [r1] ; load thread stack pointer
LDMFD r1!, {r4 - r11} ; pop r4 - r11 register
MSR psp, r1 ; update stack pointer
pendsv_exit
; restore interrupt
MSR PRIMASK, r2
ORR lr, lr, #0x04
BX lr
ENDP
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to PROC
EXPORT rt_hw_context_switch_to
; set to thread
LDR r1, =rt_interrupt_to_thread
STR r0, [r1]
; set from thread to 0
LDR r1, =rt_interrupt_from_thread
MOV r0, #0x0
STR r0, [r1]
; set interrupt flag to 1
LDR r1, =rt_thread_switch_interrupt_flag
MOV r0, #1
STR r0, [r1]
; set the PendSV exception priority
LDR r0, =NVIC_SYSPRI2
LDR r1, =NVIC_PENDSV_PRI
LDR.W r2, [r0,#0x00] ; read
ORR r1,r1,r2 ; modify
STR r1, [r0] ; write-back
; trigger the PendSV exception (causes context switch)
LDR r0, =NVIC_INT_CTRL
LDR r1, =NVIC_PENDSVSET
STR r1, [r0]
; enable interrupts at processor level
CPSIE I
; never reach here!
ENDP
; compatible with old version
rt_hw_interrupt_thread_switch PROC
EXPORT rt_hw_interrupt_thread_switch
BX lr
NOP
ENDP
IMPORT rt_hw_hard_fault_exception
EXPORT HardFault_Handler
HardFault_Handler PROC
; get current context
MRS r0, psp ; get fault thread stack pointer
PUSH {lr}
BL rt_hw_hard_fault_exception
POP {lr}
ORR lr, lr, #0x04
BX lr
ENDP
END

View File

@ -1,106 +1,106 @@
/******************************************************************//** /******************************************************************//**
* @file cpu.c * @file cpuport.c
* @brief This file is part of RT-Thread RTOS * @brief This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2011, RT-Thread Development Team * COPYRIGHT (C) 2011, RT-Thread Development Team
* @author Bernard, onelife * @author Bernard, onelife
* @version 0.4 beta * @version 0.4 beta
********************************************************************** **********************************************************************
* @section License * @section License
* The license and distribution terms for this file may be found in the file LICENSE in this * 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 * distribution or at http://www.rt-thread.org/license/LICENSE
********************************************************************** **********************************************************************
* @section Change Logs * @section Change Logs
* Date Author Notes * Date Author Notes
* 2009-01-05 Bernard first version * 2009-01-05 Bernard first version
* 2011-02-14 onelife Modify for EFM32 * 2011-02-14 onelife Modify for EFM32
* 2011-06-17 onelife Merge all of the C source code into cpuport.c * 2011-06-17 onelife Merge all of the C source code into cpuport.c
*********************************************************************/ *********************************************************************/
/******************************************************************//** /******************************************************************//**
* @addtogroup cortex-m3 * @addtogroup cortex-m3
* @{ * @{
*********************************************************************/ *********************************************************************/
/* Includes -------------------------------------------------------------------*/ /* Includes -------------------------------------------------------------------*/
#include <rtthread.h> #include <rtthread.h>
/* Private typedef -------------------------------------------------------------*/ /* Private typedef -------------------------------------------------------------*/
struct stack_contex struct stack_contex
{ {
rt_uint32_t r0; rt_uint32_t r0;
rt_uint32_t r1; rt_uint32_t r1;
rt_uint32_t r2; rt_uint32_t r2;
rt_uint32_t r3; rt_uint32_t r3;
rt_uint32_t r12; rt_uint32_t r12;
rt_uint32_t lr; rt_uint32_t lr;
rt_uint32_t pc; rt_uint32_t pc;
rt_uint32_t psr; rt_uint32_t psr;
}; };
/* Private define --------------------------------------------------------------*/ /* Private define --------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/ /* Private macro --------------------------------------------------------------*/
/* Private variables ------------------------------------------------------------*/ /* Private variables ------------------------------------------------------------*/
/* exception and interrupt handler table */ /* exception and interrupt handler table */
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag; rt_uint32_t rt_thread_switch_interrupt_flag;
/* Private function prototypes ---------------------------------------------------*/ /* Private function prototypes ---------------------------------------------------*/
/* Private functions ------------------------------------------------------------*/ /* Private functions ------------------------------------------------------------*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit) rt_uint8_t *stack_addr, void *texit)
{ {
unsigned long *stk; unsigned long *stk;
stk = (unsigned long *)stack_addr; stk = (unsigned long *)stack_addr;
*(stk) = 0x01000000L; /* PSR */ *(stk) = 0x01000000L; /* PSR */
*(--stk) = (unsigned long)tentry; /* entry point, pc */ *(--stk) = (unsigned long)tentry; /* entry point, pc */
*(--stk) = (unsigned long)texit; /* lr */ *(--stk) = (unsigned long)texit; /* lr */
*(--stk) = 0; /* r12 */ *(--stk) = 0; /* r12 */
*(--stk) = 0; /* r3 */ *(--stk) = 0; /* r3 */
*(--stk) = 0; /* r2 */ *(--stk) = 0; /* r2 */
*(--stk) = 0; /* r1 */ *(--stk) = 0; /* r1 */
*(--stk) = (unsigned long)parameter; /* r0 : argument */ *(--stk) = (unsigned long)parameter; /* r0 : argument */
*(--stk) = 0; /* r11 */ *(--stk) = 0; /* r11 */
*(--stk) = 0; /* r10 */ *(--stk) = 0; /* r10 */
*(--stk) = 0; /* r9 */ *(--stk) = 0; /* r9 */
*(--stk) = 0; /* r8 */ *(--stk) = 0; /* r8 */
*(--stk) = 0; /* r7 */ *(--stk) = 0; /* r7 */
*(--stk) = 0; /* r6 */ *(--stk) = 0; /* r6 */
*(--stk) = 0; /* r5 */ *(--stk) = 0; /* r5 */
*(--stk) = 0; /* r4 */ *(--stk) = 0; /* r4 */
/* return task's current stack address */ /* return task's current stack address */
return (rt_uint8_t *)stk; return (rt_uint8_t *)stk;
} }
extern void list_thread(void); extern void list_thread(void);
extern rt_thread_t rt_current_thread; extern rt_thread_t rt_current_thread;
void rt_hw_hard_fault_exception(struct stack_contex* contex) void rt_hw_hard_fault_exception(struct stack_contex* contex)
{ {
rt_kprintf("psr: 0x%08x\n", contex->psr); rt_kprintf("psr: 0x%08x\n", contex->psr);
rt_kprintf(" pc: 0x%08x\n", contex->pc); rt_kprintf(" pc: 0x%08x\n", contex->pc);
rt_kprintf(" lr: 0x%08x\n", contex->lr); rt_kprintf(" lr: 0x%08x\n", contex->lr);
rt_kprintf("r12: 0x%08x\n", contex->r12); rt_kprintf("r12: 0x%08x\n", contex->r12);
rt_kprintf("r03: 0x%08x\n", contex->r3); rt_kprintf("r03: 0x%08x\n", contex->r3);
rt_kprintf("r02: 0x%08x\n", contex->r2); rt_kprintf("r02: 0x%08x\n", contex->r2);
rt_kprintf("r01: 0x%08x\n", contex->r1); rt_kprintf("r01: 0x%08x\n", contex->r1);
rt_kprintf("r00: 0x%08x\n", contex->r0); rt_kprintf("r00: 0x%08x\n", contex->r0);
rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name);
#ifdef RT_USING_FINSH #ifdef RT_USING_FINSH
list_thread(); list_thread();
#endif #endif
while (1); while (1);
} }
void rt_hw_cpu_shutdown() void rt_hw_cpu_shutdown()
{ {
rt_kprintf("shutdown...\n"); rt_kprintf("shutdown...\n");
RT_ASSERT(0); RT_ASSERT(0);
} }
/******************************************************************//** /******************************************************************//**
* @} * @}
*********************************************************************/ *********************************************************************/