From 7906287cfebe97e472f9c0e6a28ad86d6d43e95b Mon Sep 17 00:00:00 2001 From: wuyangyong Date: Thu, 16 Feb 2012 03:45:50 +0000 Subject: [PATCH] IAR not support VSTMFD and VLDMFD, use VSTMDB and VLDMIA. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1947 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- libcpu/arm/cortex-m4/context_iar.S | 358 ++++++++++++++--------------- 1 file changed, 179 insertions(+), 179 deletions(-) diff --git a/libcpu/arm/cortex-m4/context_iar.S b/libcpu/arm/cortex-m4/context_iar.S index 4de0580177..dc447f1382 100644 --- a/libcpu/arm/cortex-m4/context_iar.S +++ b/libcpu/arm/cortex-m4/context_iar.S @@ -1,179 +1,179 @@ -;/* -; * File : context_iar.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 -; * 2009-09-27 Bernard add protect when contex switch occurs -; * 2012-01-01 aozima support context switch load/store FPU register. -; */ - -;/** -; * @addtogroup STM32 -; */ -;/*@{*/ - -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 - - SECTION .text:CODE(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(); -; */ - EXPORT rt_hw_interrupt_disable -rt_hw_interrupt_disable: - MRS r0, PRIMASK - CPSID I - BX LR - -;/* -; * void rt_hw_interrupt_enable(rt_base_t level); -; */ - EXPORT rt_hw_interrupt_enable -rt_hw_interrupt_enable: - MSR PRIMASK, r0 - BX LR - -;/* -; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); -; * r0 --> from -; * r1 --> to -; */ - EXPORT rt_hw_context_switch_interrupt - EXPORT rt_hw_context_switch -rt_hw_context_switch_interrupt: -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 - -; r0 --> swith from thread stack -; r1 --> swith to thread stack -; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack - EXPORT PendSV_Handler -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 - VSTMFD r1!, {d8 - d15} ; push FPU register s16~s31 - 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 - VLDMFD r1!, {d8 - d15} ; pop FPU register s16~s31 - MSR psp, r1 ; update stack pointer - -pendsv_exit - ; restore interrupt - MSR PRIMASK, r2 - - ORR lr, lr, #0x04 - BX lr - -;/* -; * void rt_hw_context_switch_to(rt_uint32 to); -; * r0 --> to -; */ - EXPORT rt_hw_context_switch_to -rt_hw_context_switch_to: - 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 - - LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) - LDR r1, =NVIC_PENDSVSET - STR r1, [r0] - - CPSIE I ; enable interrupts at processor level - - ; never reach here! - -; compatible with old version - EXPORT rt_hw_interrupt_thread_switch -rt_hw_interrupt_thread_switch: - BX lr - - IMPORT rt_hw_hard_fault_exception - EXPORT HardFault_Handler -HardFault_Handler: - - ; 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 - - END +;/* +; * File : context_iar.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 +; * 2009-09-27 Bernard add protect when contex switch occurs +; * 2012-01-01 aozima support context switch load/store FPU register. +; */ + +;/** +; * @addtogroup STM32 +; */ +;/*@{*/ + +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 + + SECTION .text:CODE(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(); +; */ + EXPORT rt_hw_interrupt_disable +rt_hw_interrupt_disable: + MRS r0, PRIMASK + CPSID I + BX LR + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ + EXPORT rt_hw_interrupt_enable +rt_hw_interrupt_enable: + MSR PRIMASK, r0 + BX LR + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ + EXPORT rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch +rt_hw_context_switch_interrupt: +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 + +; r0 --> swith from thread stack +; r1 --> swith to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack + EXPORT PendSV_Handler +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 + VSTMDB r1!, {d8 - d15} ; push FPU register s16~s31 + 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 + VLDMIA r1!, {d8 - d15} ; pop FPU register s16~s31 + MSR psp, r1 ; update stack pointer + +pendsv_exit + ; restore interrupt + MSR PRIMASK, r2 + + ORR lr, lr, #0x04 + BX lr + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; */ + EXPORT rt_hw_context_switch_to +rt_hw_context_switch_to: + 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 + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + + CPSIE I ; enable interrupts at processor level + + ; never reach here! + +; compatible with old version + EXPORT rt_hw_interrupt_thread_switch +rt_hw_interrupt_thread_switch: + BX lr + + IMPORT rt_hw_hard_fault_exception + EXPORT HardFault_Handler +HardFault_Handler: + + ; 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 + + END -- GitLab