git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@6964 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
e1fe47b7f9
commit
ffdbef26d6
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
2011,2012,2013 Giovanni Di Sirio.
|
2011,2012,2013 Giovanni Di Sirio.
|
||||||
|
|
||||||
This file is part of ChibiOS/RT.
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
@ -28,133 +28,135 @@
|
||||||
|
|
||||||
#if !defined(__DOXYGEN__)
|
#if !defined(__DOXYGEN__)
|
||||||
|
|
||||||
.set MODE_USR, 0x10
|
.set MODE_USR, 0x10
|
||||||
.set MODE_FIQ, 0x11
|
.set MODE_FIQ, 0x11
|
||||||
.set MODE_IRQ, 0x12
|
.set MODE_IRQ, 0x12
|
||||||
.set MODE_SVC, 0x13
|
.set MODE_SVC, 0x13
|
||||||
.set MODE_ABT, 0x17
|
.set MODE_ABT, 0x17
|
||||||
.set MODE_UND, 0x1B
|
.set MODE_UND, 0x1B
|
||||||
.set MODE_SYS, 0x1F
|
.set MODE_SYS, 0x1F
|
||||||
|
|
||||||
.set I_BIT, 0x80
|
.set I_BIT, 0x80
|
||||||
.set F_BIT, 0x40
|
.set F_BIT, 0x40
|
||||||
|
|
||||||
.text
|
.text
|
||||||
.code 32
|
.code 32
|
||||||
.balign 4
|
.balign 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset handler.
|
* Reset handler.
|
||||||
*/
|
*/
|
||||||
.global Reset_Handler
|
.global Reset_Handler
|
||||||
Reset_Handler:
|
Reset_Handler:
|
||||||
/*
|
/*
|
||||||
* Stack pointers initialization.
|
* Stack pointers initialization.
|
||||||
*/
|
*/
|
||||||
ldr r0, =___stacks_end__
|
ldr r0, =___stacks_end__
|
||||||
/* Undefined */
|
/* Undefined */
|
||||||
msr CPSR_c, #MODE_UND | I_BIT | F_BIT
|
msr CPSR_c, #MODE_UND | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
ldr r1, =__und_stack_size__
|
ldr r1, =__und_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
/* Abort */
|
/* Abort */
|
||||||
msr CPSR_c, #MODE_ABT | I_BIT | F_BIT
|
msr CPSR_c, #MODE_ABT | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
ldr r1, =__abt_stack_size__
|
ldr r1, =__abt_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
/* FIQ */
|
/* FIQ */
|
||||||
msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
|
msr CPSR_c, #MODE_FIQ | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
ldr r1, =__fiq_stack_size__
|
ldr r1, =__fiq_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
/* IRQ */
|
/* IRQ */
|
||||||
msr CPSR_c, #MODE_IRQ | I_BIT | F_BIT
|
msr CPSR_c, #MODE_IRQ | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
ldr r1, =__irq_stack_size__
|
ldr r1, =__irq_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
/* Supervisor */
|
/* Supervisor */
|
||||||
msr CPSR_c, #MODE_SVC | I_BIT | F_BIT
|
msr CPSR_c, #MODE_SVC | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
ldr r1, =__svc_stack_size__
|
ldr r1, =__svc_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
/* System */
|
/* System */
|
||||||
msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
|
msr CPSR_c, #MODE_SYS | I_BIT | F_BIT
|
||||||
mov sp, r0
|
mov sp, r0
|
||||||
// ldr r1, =__sys_stack_size__
|
// ldr r1, =__sys_stack_size__
|
||||||
// sub r0, r0, r1
|
// sub r0, r0, r1
|
||||||
/*
|
/*
|
||||||
* Early initialization.
|
* Early initialization.
|
||||||
*/
|
*/
|
||||||
#ifndef THUMB_NO_INTERWORKING
|
#if !defined(THUMB_NO_INTERWORKING)
|
||||||
bl __early_init
|
bl __early_init
|
||||||
#else
|
#else /* defined(THUMB_NO_INTERWORKING) */
|
||||||
add r0, pc, #1
|
add r0, pc, #1
|
||||||
bx r0
|
bx r0
|
||||||
.code 16
|
.code 16
|
||||||
bl __early_init
|
bl __early_init
|
||||||
mov r0, pc
|
mov r0, pc
|
||||||
bx r0
|
bx r0
|
||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif /* defined(THUMB_NO_INTERWORKING) */
|
||||||
/*
|
|
||||||
* Data initialization.
|
/*
|
||||||
* NOTE: It assumes that the DATA size is a multiple of 4.
|
* Data initialization.
|
||||||
*/
|
* NOTE: It assumes that the DATA size is a multiple of 4.
|
||||||
ldr r1, =_textdata
|
*/
|
||||||
ldr r2, =_data
|
ldr r1, =_textdata
|
||||||
ldr r3, =_edata
|
ldr r2, =_data
|
||||||
|
ldr r3, =_edata
|
||||||
dataloop:
|
dataloop:
|
||||||
cmp r2, r3
|
cmp r2, r3
|
||||||
ldrlo r0, [r1], #4
|
ldrlo r0, [r1], #4
|
||||||
strlo r0, [r2], #4
|
strlo r0, [r2], #4
|
||||||
blo dataloop
|
blo dataloop
|
||||||
/*
|
/*
|
||||||
* BSS initialization.
|
* BSS initialization.
|
||||||
* NOTE: It assumes that the BSS size is a multiple of 4.
|
* NOTE: It assumes that the BSS size is a multiple of 4.
|
||||||
*/
|
*/
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
ldr r1, =_bss_start
|
ldr r1, =_bss_start
|
||||||
ldr r2, =_bss_end
|
ldr r2, =_bss_end
|
||||||
bssloop:
|
bssloop:
|
||||||
cmp r1, r2
|
cmp r1, r2
|
||||||
strlo r0, [r1], #4
|
strlo r0, [r1], #4
|
||||||
blo bssloop
|
blo bssloop
|
||||||
/*
|
/*
|
||||||
* Late initialization.
|
* Late initialization.
|
||||||
*/
|
*/
|
||||||
#ifndef THUMB_NO_INTERWORKING
|
#if !defined(THUMB_NO_INTERWORKING)
|
||||||
bl __late_init
|
bl __late_init
|
||||||
#else
|
#else /* defined(THUMB_NO_INTERWORKING) */
|
||||||
add r0, pc, #1
|
add r0, pc, #1
|
||||||
bx r0
|
bx r0
|
||||||
.code 16
|
.code 16
|
||||||
bl __late_init
|
bl __late_init
|
||||||
mov r0, pc
|
mov r0, pc
|
||||||
bx r0
|
bx r0
|
||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif /* defined(THUMB_NO_INTERWORKING) */
|
||||||
/*
|
|
||||||
* Main program invocation.
|
/*
|
||||||
*/
|
* Main program invocation.
|
||||||
#ifdef THUMB_NO_INTERWORKING
|
*/
|
||||||
add r0, pc, #1
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
bx r0
|
add r0, pc, #1
|
||||||
.code 16
|
bx r0
|
||||||
bl main
|
.code 16
|
||||||
ldr r1, =_main_exit_handler
|
bl main
|
||||||
bx r1
|
ldr r1, =_main_exit_handler
|
||||||
.code 32
|
bx r1
|
||||||
#else
|
.code 32
|
||||||
bl main
|
#else /* !defined(THUMB_NO_INTERWORKING)
|
||||||
b _main_exit_handler
|
bl main
|
||||||
#endif
|
b _main_exit_handler
|
||||||
|
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default main function exit handler.
|
* Default main function exit handler.
|
||||||
*/
|
*/
|
||||||
.weak _main_exit_handler
|
.weak _main_exit_handler
|
||||||
_main_exit_handler:
|
_main_exit_handler:
|
||||||
.loop: b .loop
|
.loop: b .loop
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default early initialization code. It is declared weak in order to be
|
* Default early initialization code. It is declared weak in order to be
|
||||||
|
@ -162,14 +164,14 @@ _main_exit_handler:
|
||||||
* Early initialization is performed just before reset before BSS and DATA
|
* Early initialization is performed just before reset before BSS and DATA
|
||||||
* segments initialization.
|
* segments initialization.
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_NO_INTERWORKING
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
.thumb_func
|
.thumb_func
|
||||||
.code 16
|
.code 16
|
||||||
#endif
|
#endif
|
||||||
.weak __early_init
|
.weak __early_init
|
||||||
__early_init:
|
__early_init:
|
||||||
bx lr
|
bx lr
|
||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -178,14 +180,14 @@ __early_init:
|
||||||
* Early initialization is performed just after reset before BSS and DATA
|
* Early initialization is performed just after reset before BSS and DATA
|
||||||
* segments initialization.
|
* segments initialization.
|
||||||
*/
|
*/
|
||||||
#ifdef THUMB_NO_INTERWORKING
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
.thumb_func
|
.thumb_func
|
||||||
.code 16
|
.code 16
|
||||||
#endif
|
#endif
|
||||||
.weak __late_init
|
.weak __late_init
|
||||||
__late_init:
|
__late_init:
|
||||||
bx lr
|
bx lr
|
||||||
.code 32
|
.code 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011,2012,2013 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ARM/compilers/GCC/vectors.s
|
||||||
|
* @brief Interrupt vectors for ARM devices.
|
||||||
|
*
|
||||||
|
* @defgroup ARM_VECTORS ARM Exception Vectors
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Unhandled exceptions handler.
|
||||||
|
* @details Any undefined exception vector points to this function by default.
|
||||||
|
* This function simply stops the system into an infinite loop.
|
||||||
|
* @note The default implementation is a weak symbol, the application
|
||||||
|
* can override the default implementation.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _unhandled_exception(void) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
.section vectors
|
||||||
|
.code 32
|
||||||
|
.balign 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System entry points.
|
||||||
|
*/
|
||||||
|
_start:
|
||||||
|
ldr pc, _reset
|
||||||
|
ldr pc, _undefined
|
||||||
|
ldr pc, _swi
|
||||||
|
ldr pc, _prefetch
|
||||||
|
ldr pc, _abort
|
||||||
|
nop
|
||||||
|
ldr pc, _irq
|
||||||
|
ldr pc, _fiq
|
||||||
|
|
||||||
|
_reset:
|
||||||
|
.word ResetHandler
|
||||||
|
_undefined:
|
||||||
|
.word UndHandler
|
||||||
|
_swi:
|
||||||
|
.word SwiHandler
|
||||||
|
_prefetch:
|
||||||
|
.word PrefetchHandler
|
||||||
|
_abort:
|
||||||
|
.word AbortHandler
|
||||||
|
_fiq:
|
||||||
|
.word FiqHandler
|
||||||
|
_irq:
|
||||||
|
.word IrqHandler
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default exceptions handlers. The handlers are declared weak in order to be
|
||||||
|
* replaced by the real handling code. Everything is defaulted to an infinite
|
||||||
|
* loop.
|
||||||
|
*/
|
||||||
|
.weak ResetHandler
|
||||||
|
ResetHandler:
|
||||||
|
.weak UndHandler
|
||||||
|
UndHandler:
|
||||||
|
.weak SwiHandler
|
||||||
|
SwiHandler:
|
||||||
|
.weak PrefetchHandler
|
||||||
|
PrefetchHandler:
|
||||||
|
.weak AbortHandler
|
||||||
|
AbortHandler:
|
||||||
|
.weak FiqHandler
|
||||||
|
FiqHandler:
|
||||||
|
.weak IrqHandler
|
||||||
|
IrqHandler:
|
||||||
|
.weak _unhandled_exception
|
||||||
|
_unhandled_exception:
|
||||||
|
b _unhandled_exception
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -19,7 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file ARMCMx/GCC/vectors.c
|
* @file ARMCMx/compilers/GCC/vectors.c
|
||||||
* @brief Interrupt vectors for Cortex-Mx devices.
|
* @brief Interrupt vectors for Cortex-Mx devices.
|
||||||
*
|
*
|
||||||
* @defgroup ARMCMx_VECTORS Cortex-Mx Interrupt Vectors
|
* @defgroup ARMCMx_VECTORS Cortex-Mx Interrupt Vectors
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||||
|
2011,2012,2013 Giovanni Di Sirio.
|
||||||
|
|
||||||
|
This file is part of ChibiOS/RT.
|
||||||
|
|
||||||
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ARM/compilers/GCC/chcoreasm.s
|
||||||
|
* @brief ARM architecture port low level code.
|
||||||
|
*
|
||||||
|
* @addtogroup ARM_CORE
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "chconf.h"
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#if !defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
.set MODE_USR, 0x10
|
||||||
|
.set MODE_FIQ, 0x11
|
||||||
|
.set MODE_IRQ, 0x12
|
||||||
|
.set MODE_SVC, 0x13
|
||||||
|
.set MODE_ABT, 0x17
|
||||||
|
.set MODE_UND, 0x1B
|
||||||
|
.set MODE_SYS, 0x1F
|
||||||
|
|
||||||
|
.equ I_BIT, 0x80
|
||||||
|
.equ F_BIT, 0x40
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt enable/disable functions, only present if there is THUMB code in
|
||||||
|
* the system because those are inlined in ARM code.
|
||||||
|
*/
|
||||||
|
#if defined(THUMB_PRESENT)
|
||||||
|
.balign 16
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_disable_thumb
|
||||||
|
_port_disable_thumb:
|
||||||
|
mov r3, pc
|
||||||
|
bx r3
|
||||||
|
.code 32
|
||||||
|
mrs r3, CPSR
|
||||||
|
orr r3, #I_BIT
|
||||||
|
msr CPSR_c, r3
|
||||||
|
orr r3, #F_BIT
|
||||||
|
msr CPSR_c, r3
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.balign 16
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_suspend_thumb
|
||||||
|
_port_suspend_thumb:
|
||||||
|
// Goes into _port_unlock_thumb
|
||||||
|
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_lock_thumb
|
||||||
|
_port_lock_thumb:
|
||||||
|
mov r3, pc
|
||||||
|
bx r3
|
||||||
|
.code 32
|
||||||
|
msr CPSR_c, #MODE_SYS | I_BIT
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.balign 16
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_enable_thumb
|
||||||
|
_port_enable_thumb:
|
||||||
|
// Goes into _port_unlock_thumb
|
||||||
|
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_unlock_thumb
|
||||||
|
_port_unlock_thumb:
|
||||||
|
mov r3, pc
|
||||||
|
bx r3
|
||||||
|
.code 32
|
||||||
|
msr CPSR_c, #MODE_SYS
|
||||||
|
bx lr
|
||||||
|
#endif /* defined(THUMB_PRESENT) */
|
||||||
|
|
||||||
|
.balign 16
|
||||||
|
#if defined(THUMB_PRESENT)
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.global _port_switch_thumb
|
||||||
|
_port_switch_thumb:
|
||||||
|
mov r2, pc
|
||||||
|
bx r2
|
||||||
|
// Goes into _port_switch_arm in ARM mode
|
||||||
|
#endif /* defined(THUMB_PRESENT) */
|
||||||
|
|
||||||
|
.code 32
|
||||||
|
.global _port_switch_arm
|
||||||
|
_port_switch_arm:
|
||||||
|
stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||||
|
str sp, [r1, #12]
|
||||||
|
ldr sp, [r0, #12]
|
||||||
|
#if defined(THUMB_PRESENT)
|
||||||
|
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||||
|
bx lr
|
||||||
|
#else /* !defined(THUMB_PRESENT)T */
|
||||||
|
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||||
|
#endif /* !defined(THUMB_PRESENT) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Common exit point for all IRQ routines, it performs the rescheduling if
|
||||||
|
* required.
|
||||||
|
* System stack frame structure after a context switch in the
|
||||||
|
* interrupt handler:
|
||||||
|
*
|
||||||
|
* High +------------+
|
||||||
|
* | LR_USR | -+
|
||||||
|
* | r12 | |
|
||||||
|
* | r3 | |
|
||||||
|
* | r2 | | External context: IRQ handler frame
|
||||||
|
* | r1 | |
|
||||||
|
* | r0 | |
|
||||||
|
* | PC | | (user code return address)
|
||||||
|
* | PSR_USR | -+ (user code status)
|
||||||
|
* | .... | <- chSchDoReschedule() stack frame, optimize it for space
|
||||||
|
* | LR | -+ (system code return address)
|
||||||
|
* | r11 | |
|
||||||
|
* | r10 | |
|
||||||
|
* | r9 | |
|
||||||
|
* | r8 | | Internal context: chSysSwitch() frame
|
||||||
|
* | r7 | |
|
||||||
|
* | r6 | |
|
||||||
|
* | r5 | |
|
||||||
|
* SP-> | r4 | -+
|
||||||
|
* Low +------------+
|
||||||
|
*/
|
||||||
|
.balign 16
|
||||||
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
.globl _port_irq_common
|
||||||
|
_port_irq_common:
|
||||||
|
bl chSchIsPreemptionRequired
|
||||||
|
mov lr, pc
|
||||||
|
bx lr
|
||||||
|
.code 32
|
||||||
|
|
||||||
|
#else /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
.code 32
|
||||||
|
.globl _port_irq_common
|
||||||
|
_port_irq_common:
|
||||||
|
bl chSchIsPreemptionRequired
|
||||||
|
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
|
||||||
|
cmp r0, #0 // Simply returns if a
|
||||||
|
ldmeqfd sp!, {r0-r3, r12, lr} // reschedule is not
|
||||||
|
subeqs pc, lr, #4 // required.
|
||||||
|
|
||||||
|
// Saves the IRQ mode registers in the system stack.
|
||||||
|
ldmfd sp!, {r0-r3, r12, lr} // IRQ stack now empty.
|
||||||
|
msr CPSR_c, #MODE_SYS | I_BIT
|
||||||
|
stmfd sp!, {r0-r3, r12, lr} // Registers on System Stack.
|
||||||
|
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||||
|
mrs r0, SPSR
|
||||||
|
mov r1, lr
|
||||||
|
msr CPSR_c, #MODE_SYS | I_BIT
|
||||||
|
stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
|
||||||
|
|
||||||
|
// Context switch.
|
||||||
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
|
add r0, pc, #1
|
||||||
|
bx r0
|
||||||
|
.code 16
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
bl dbg_check_lock
|
||||||
|
#endif
|
||||||
|
bl chSchDoReschedule
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
bl dbg_check_unlock
|
||||||
|
#endif
|
||||||
|
mov lr, pc
|
||||||
|
bx lr
|
||||||
|
.code 32
|
||||||
|
#else /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
bl dbg_check_lock
|
||||||
|
#endif
|
||||||
|
bl chSchDoReschedule
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
bl dbg_check_unlock
|
||||||
|
#endif
|
||||||
|
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
|
||||||
|
// Re-establish the IRQ conditions again.
|
||||||
|
ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
|
||||||
|
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||||
|
msr SPSR_fsxc, r0
|
||||||
|
mov lr, r1
|
||||||
|
msr CPSR_c, #MODE_SYS | I_BIT
|
||||||
|
ldmfd sp!, {r0-r3, r12, lr}
|
||||||
|
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||||
|
subs pc, lr, #4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Threads trampoline code.
|
||||||
|
* NOTE: The threads always start in ARM mode and then switches to the
|
||||||
|
* thread-function mode.
|
||||||
|
*/
|
||||||
|
.balign 16
|
||||||
|
.code 32
|
||||||
|
.globl _port_thread_start
|
||||||
|
_port_thread_start:
|
||||||
|
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||||
|
mov r0, #0
|
||||||
|
ldr r1, =dbg_lock_cnt
|
||||||
|
str r0, [r1]
|
||||||
|
#endif
|
||||||
|
msr CPSR_c, #MODE_SYS
|
||||||
|
#if defined(THUMB_NO_INTERWORKING)
|
||||||
|
mov r0, r5
|
||||||
|
mov lr, pc
|
||||||
|
bx r4
|
||||||
|
bl chThdExit
|
||||||
|
#else /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
add r0, pc, #1
|
||||||
|
bx r0
|
||||||
|
.code 16
|
||||||
|
mov r0, r5
|
||||||
|
bl jmpr4
|
||||||
|
bl chThdExit
|
||||||
|
jmpr4:
|
||||||
|
bx r4
|
||||||
|
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||||
|
|
||||||
|
#endif /* !defined(__DOXYGEN__) */
|
||||||
|
|
||||||
|
/** @} */
|
Loading…
Reference in New Issue