v7m alt port working, options not tested.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14847 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-09-29 12:28:50 +00:00
parent 0f41984602
commit 4dd944b332
6 changed files with 180 additions and 155 deletions

View File

@ -66,7 +66,7 @@ thread_t *port_schedule_next(void) {
chSysLock(); chSysLock();
/* TODO statistics, tracing etc */ /* TODO statistics, tracing etc */
ntp = chSchSelectFirstI(); ntp = chSchSelectFirst();
chSysUnlock(); chSysUnlock();

View File

@ -67,7 +67,7 @@
/** /**
* @brief Disabled value for BASEPRI register. * @brief Disabled value for BASEPRI register.
*/ */
#define CORTEX_BASEPRI_DISABLED 0U #define CORTEX_BASEPRI_DISABLED 0
/** /**
* @brief Total priority levels. * @brief Total priority levels.
@ -85,7 +85,7 @@
* @brief Maximum priority level. * @brief Maximum priority level.
* @details The maximum allowed priority level is always zero. * @details The maximum allowed priority level is always zero.
*/ */
#define CORTEX_MAXIMUM_PRIORITY 0U #define CORTEX_MAXIMUM_PRIORITY 0
/** /**
* @brief SVCALL handler priority. * @brief SVCALL handler priority.
@ -471,9 +471,6 @@ struct port_context {
uint32_t r9; uint32_t r9;
uint32_t r10; uint32_t r10;
uint32_t r11; uint32_t r11;
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || defined(__DOXYGEN__)
uint32_t splim;
#endif
uint32_t lr_exc; uint32_t lr_exc;
#if (CORTEX_USE_FPU == TRUE) || defined(__DOXYGEN__) #if (CORTEX_USE_FPU == TRUE) || defined(__DOXYGEN__)
uint32_t s16; uint32_t s16;

View File

@ -18,10 +18,10 @@
*/ */
/** /**
* @file ARMv7-M/compilers/GCC/chcoreasm.S * @file ARMv7-M-ALT/compilers/GCC/chcoreasm.S
* @brief ARMv7-M port low level code. * @brief ARMv7-M (alternate) architecture port low level code.
* *
* @addtogroup ARMV7M_GCC_CORE * @addtogroup ARMV7M_ALT_GCC_CORE
* @{ * @{
*/ */
@ -44,9 +44,11 @@
* RTOS-specific context offset. * RTOS-specific context offset.
*/ */
#if defined(_CHIBIOS_RT_CONF_) #if defined(_CHIBIOS_RT_CONF_)
#define CURRENT_OFFSET 12
#define CONTEXT_OFFSET 12 #define CONTEXT_OFFSET 12
#elif defined(_CHIBIOS_NIL_CONF_) #elif defined(_CHIBIOS_NIL_CONF_)
#define CURRENT_OFFSET 0 /* nil.current */
#define CONTEXT_OFFSET 0 #define CONTEXT_OFFSET 0
#else #else
@ -54,12 +56,9 @@
#endif #endif
/* MPU-related constants.*/ /* MPU-related constants.*/
#define MPU_RNR 0xE000ED98
#define MPU_RBAR 0xE000ED9C #define MPU_RBAR 0xE000ED9C
/* Other constants.*/
#define SCB_ICSR 0xE000ED04
#define ICSR_PENDSVSET 0x10000000
.syntax unified .syntax unified
.cpu cortex-m4 .cpu cortex-m4
#if CORTEX_USE_FPU #if CORTEX_USE_FPU
@ -72,106 +71,179 @@
.text .text
/*--------------------------------------------------------------------------* /*--------------------------------------------------------------------------*
* Performs a context switch between two threads. * Context switch macros depending on various options.
*--------------------------------------------------------------------------*/
/* Store integer context through R1.*/
.macro PORT_STORE_INTEGER_CONTEXT
mrs r2, PSP
mrs r3, BASEPRI
stmia r1!, {r2-r11,lr}
.endm
/* Load integer context through R0.*/
.macro PORT_RESTORE_INTEGER_CONTEXT
ldmia r0!, {r2-r11, lr}
msr PSP, r2
msr BASEPRI, r3
.endm
#if CORTEX_USE_FPU
/* Store float context through R1.*/
.macro PORT_STORE_FLOAT_CONTEXT
vstmia r1!, {s16-s31}
.endm
/* Load float context through R0.*/
.macro PORT_RESTORE_FLOAT_CONTEXT
vldmia r0!, {s16-s31}
.endm
#else
.macro PORT_STORE_FLOAT_CONTEXT
.endm
.macro PORT_RESTORE_FLOAT_CONTEXT
.endm
#endif
/* Store MPU context through R1.*/
.macro PORT_STORE_MPU_CONTEXT
#if PORT_SWITCHED_REGIONS_NUMBER == 1
ldr r2, =MPU_RBAR
mov r3, #0
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR0, RASR0 */
stmia r1!, {r4-r5}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 2
ldr r2, =MPU_RBAR
mov r3, #0
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR0, RASR0 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r6, r7} /* RBAR1, RASR1 */
stmia r1!, {r4-r7}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 3
ldr r2, =MPU_RBAR
mov r3, #0
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR0, RASR0 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r6, r7} /* RBAR1, RASR1 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r8, r9} /* RBAR2, RASR2 */
stmia r1!, {r4-r9}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 4
ldr r2, =MPU_RBAR
mov r3, #0
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR0, RASR0 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r6, r7} /* RBAR1, RASR1 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r8, r9} /* RBAR2, RASR2 */
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r10, r11} /* RBAR3, RASR3 */
stmia r1!, {r4-r11}
#endif
.endm
/* Load MPU context through R0.*/
.macro PORT_LOAD_MPU_CONTEXT
#if PORT_SWITCHED_REGIONS_NUMBER == 1
ldr r2, =MPU_RNR
mov r3, #0
ldmia r0!, {r4-r5}
stm r2, {r3, r4-r5} /* RNR, RBAR0, RASR0 */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 2
ldr r2, =MPU_RNR
mov r3, #0
ldmia r0!, {r4-r7}
stm r2, {r3, r4-r5} /* RNR, RBAR0, RASR0 */
add r3, #1
stm r2, {r3, r6-r7} /* RNR, RBAR1, RASR1 */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 3
ldr r2, =MPU_RNR
mov r3, #0
ldmia r0!, {r4-r9}
stm r2, {r3, r4-r5} /* RNR, RBAR0, RASR0 */
add r3, #1
stm r2, {r3, r6-r7} /* RNR, RBAR1, RASR1 */
add r3, #1
stm r2, {r3, r8-r9} /* RNR, RBAR2, RASR2 */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 4
ldr r2, =MPU_RNR
mov r3, #0
ldmia r0!, {r4-r11}
stm r2, {r3, r4-r5} /* RNR, RBAR0, RASR0 */
add r3, #1
stm r2, {r3, r6-r7} /* RNR, RBAR1, RASR1 */
add r3, #1
stm r2, {r3, r8-r9} /* RNR, RBAR2, RASR2 */
add r3, #1
stm r2, {r3, r10-r11} /* RNR, RBAR3, RASR3 */
#endif
.endm
/*--------------------------------------------------------------------------*
* Performs a context switch between two threads using SVC.
*--------------------------------------------------------------------------*/ *--------------------------------------------------------------------------*/
.thumb_func .thumb_func
.globl __port_switch .globl SVC_Handler
__port_switch: SVC_Handler:
push {r4, r5, r6, r7, r8, r9, r10, r11, lr} /* Context store for old thread.*/
#if CORTEX_USE_FPU adds r1, #CONTEXT_OFFSET
/* Saving FPU context.*/ PORT_STORE_INTEGER_CONTEXT
vpush {s16-s31} PORT_STORE_FLOAT_CONTEXT
#endif PORT_STORE_MPU_CONTEXT
#if PORT_SWITCHED_REGIONS_NUMBER > 0 /* Context load for new thread.*/
/* Saving MPU context.*/ adds r0, #CONTEXT_OFFSET
ldr r2, =MPU_RBAR PORT_RESTORE_INTEGER_CONTEXT
#if PORT_SWITCHED_REGIONS_NUMBER >= 1 PORT_RESTORE_FLOAT_CONTEXT
mov r3, #0 PORT_LOAD_MPU_CONTEXT
str r3, [r2, #-4] /* RNR */
ldm r2, {r4, r5} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 2
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r6, r7} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 3
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r8, r9} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 4
add r3, #1
str r3, [r2, #-4] /* RNR */
ldm r2, {r10, r11} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 1
push {r4, r5}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 2
push {r4, r5, r6, r7}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 3
push {r4, r5, r6, r7, r8, r9}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER == 4
push {r4, r5, r6, r7, r8, r9, r10, r11}
#endif
#endif
str sp, [r1, #CONTEXT_OFFSET] bx lr
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \
((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4))
/* Workaround for ARM errata 752419, only applied if
condition exists for it to be triggered.*/
ldr r3, [r0, #CONTEXT_OFFSET]
mov sp, r3
#else
ldr sp, [r0, #CONTEXT_OFFSET]
#endif
#if PORT_SWITCHED_REGIONS_NUMBER > 0 /*--------------------------------------------------------------------------*
/* Restoring MPU context.*/ * Tail preemption check using PENDSV.
#if PORT_SWITCHED_REGIONS_NUMBER == 1 *--------------------------------------------------------------------------*/
pop {r4, r5} .thumb_func
#endif .globl PendSV_Handler
#if PORT_SWITCHED_REGIONS_NUMBER == 2 PendSV_Handler:
pop {r4, r5, r6, r7} /* Pointer to the current instance, assuming single instance.*/
#endif ldr r0, =ch0
#if PORT_SWITCHED_REGIONS_NUMBER == 3 // movw r0, #:lower16:ch
pop {r4, r5, r6, r7, r8, r9} // movt r0, #:upper16:ch
#endif ldr r1, [r0, #CURRENT_OFFSET]
#if PORT_SWITCHED_REGIONS_NUMBER == 4
pop {r4, r5, r6, r7, r8, r9, r10, r11}
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 1
mov r3, #0
str r3, [r2, #-4] /* RNR */
stm r2, {r4, r5} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 2
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r6, r7} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 3
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r8, r9} /* RBAR, RASR */
#endif
#if PORT_SWITCHED_REGIONS_NUMBER >= 4
add r3, #1
str r3, [r2, #-4] /* RNR */
stm r2, {r10, r11} /* RBAR, RASR */
#endif
#endif
#if CORTEX_USE_FPU /* Context store for old thread.*/
/* Restoring FPU context.*/ adds r1, #CONTEXT_OFFSET
vpop {s16-s31} PORT_STORE_INTEGER_CONTEXT
#endif PORT_STORE_FLOAT_CONTEXT
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} PORT_STORE_MPU_CONTEXT
/* Selecting the thread to be swapped in, R0 points to it.*/
bl port_schedule_next
/* Context load for new thread.*/
adds r0, #CONTEXT_OFFSET
PORT_RESTORE_INTEGER_CONTEXT
PORT_RESTORE_FLOAT_CONTEXT
PORT_LOAD_MPU_CONTEXT
bx lr
/*--------------------------------------------------------------------------* /*--------------------------------------------------------------------------*
* Start a thread by invoking its work function. * Start a thread by invoking its work function.
@ -184,61 +256,17 @@ __port_switch:
.thumb_func .thumb_func
.globl __port_thread_start .globl __port_thread_start
__port_thread_start: __port_thread_start:
#if CH_DBG_ENABLE_STACK_CHECK && PORT_ENABLE_GUARD_PAGES
bl __port_set_region
#endif
#if CH_DBG_SYSTEM_STATE_CHECK
bl __dbg_check_unlock
#endif
#if CH_DBG_STATISTICS #if CH_DBG_STATISTICS
bl __stats_stop_measure_crit_thd bl __stats_stop_measure_crit_thd
#endif #endif
#if CORTEX_SIMPLIFIED_PRIORITY movs r3, #CORTEX_BASEPRI_DISABLED
cpsie i
#else
movs r3, #0 /* CORTEX_BASEPRI_DISABLED */
msr BASEPRI, r3 msr BASEPRI, r3
#endif
mov r0, r5 mov r0, r5
blx r4 blx r4
movs r0, #0 /* MSG_OK */ movs r0, #0 /* MSG_OK */
bl chThdExit bl chThdExit
.zombies: b .zombies .zombies: b .zombies
/*--------------------------------------------------------------------------*
* Post-IRQ switch code.
*
* Exception handlers return here for context switching.
*--------------------------------------------------------------------------*/
.thumb_func
.globl __port_switch_from_isr
__port_switch_from_isr:
#if CH_DBG_STATISTICS
bl __stats_start_measure_crit_thd
#endif
#if CH_DBG_SYSTEM_STATE_CHECK
bl __dbg_check_lock
#endif
bl chSchDoPreemption
#if CH_DBG_SYSTEM_STATE_CHECK
bl __dbg_check_unlock
#endif
#if CH_DBG_STATISTICS
bl __stats_stop_measure_crit_thd
#endif
.globl __port_exit_from_isr
__port_exit_from_isr:
#if CORTEX_SIMPLIFIED_PRIORITY
movw r3, #:lower16:SCB_ICSR
movt r3, #:upper16:SCB_ICSR
mov r2, ICSR_PENDSVSET
str r2, [r3, #0]
cpsie i
#else /* !CORTEX_SIMPLIFIED_PRIORITY */
svc #0
#endif /* !CORTEX_SIMPLIFIED_PRIORITY */
.L1: b .L1
#endif /* !defined(__DOXYGEN__) */ #endif /* !defined(__DOXYGEN__) */
/** @} */ /** @} */

View File

@ -75,7 +75,7 @@ thread_t *port_schedule_next(void) {
chSysLock(); chSysLock();
/* TODO statistics, tracing etc */ /* TODO statistics, tracing etc */
ntp = chSchSelectFirstI(); ntp = chSchSelectFirst();
chSysUnlock(); chSysUnlock();

View File

@ -157,7 +157,7 @@ extern "C" {
void chSchDoPreemption(void); void chSchDoPreemption(void);
void chSchPreemption(void); void chSchPreemption(void);
void chSchDoYieldS(void); void chSchDoYieldS(void);
thread_t *chSchSelectFirstI(void); thread_t *chSchSelectFirst(void);
#if CH_CFG_OPTIMIZE_SPEED == FALSE #if CH_CFG_OPTIMIZE_SPEED == FALSE
void ch_sch_prio_insert(ch_queue_t *qp, ch_queue_t *tp); void ch_sch_prio_insert(ch_queue_t *qp, ch_queue_t *tp);
#endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */ #endif /* CH_CFG_OPTIMIZE_SPEED == FALSE */

View File

@ -620,7 +620,7 @@ void chSchDoYieldS(void) {
* *
* @special * @special
*/ */
thread_t *chSchSelectFirstI(void) { thread_t *chSchSelectFirst(void) {
os_instance_t *oip = currcore; os_instance_t *oip = currcore;
thread_t *otp = __instance_get_currthread(oip); thread_t *otp = __instance_get_currthread(oip);
thread_t *ntp; thread_t *ntp;