arch: arm: Add Cortex-R support

This adds initial Cortex-R support for interrupts and context switching.

Signed-off-by: Bradley Bolen <bbolen@lexmark.com>
This commit is contained in:
Bradley Bolen 2018-06-25 09:15:14 -04:00 committed by Ioannis Glaropoulos
commit c30a71df95
37 changed files with 1516 additions and 82 deletions

View file

@ -64,7 +64,9 @@ SECTION_FUNC(TEXT, __pendsv)
add r0, r2
/* save callee-saved + psp in thread */
#if defined(CONFIG_CPU_CORTEX_M)
mrs ip, PSP
#endif
#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
/* Store current r4-r7 */
@ -99,6 +101,10 @@ out_fp_active:
out_fp_endif:
str r0, [r2, #_thread_offset_to_mode]
#endif /* CONFIG_FP_SHARING */
#elif defined(CONFIG_ARMV7_R)
/* Store rest of process context */
mrs r12, SPSR
stm r0, {r4-r12,sp,lr}^
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
@ -110,6 +116,11 @@ out_fp_endif:
movs.n r0, #_EXC_IRQ_DEFAULT_PRIO
msr BASEPRI, r0
isb /* Make the effect of disabling interrupts be realized immediately */
#elif defined(CONFIG_ARMV7_R)
/*
* Interrupts are still disabled from __swap so empty clause
* here to avoid the preprocessor error below
*/
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
@ -121,8 +132,10 @@ out_fp_endif:
* to pend PendSV have been taken with the current kernel
* state and this is what we're handling currently.
*/
#if defined(CONFIG_CPU_CORTEX_M)
ldr v4, =_SCS_ICSR
ldr v3, =_SCS_ICSR_UNPENDSV
#endif
/* _kernel is still in r1 */
@ -141,7 +154,9 @@ out_fp_endif:
*/
/* _SCS_ICSR is still in v4 and _SCS_ICSR_UNPENDSV in v3 */
#if defined(CONFIG_CPU_CORTEX_M)
str v3, [v4, #0]
#endif
/* Restore previous interrupt disable state (irq_lock key) */
#if (defined(CONFIG_CPU_CORTEX_M0PLUS) || defined(CONFIG_CPU_CORTEX_M0)) && \
@ -158,7 +173,7 @@ out_fp_endif:
str r3, [r4]
#else
ldr r0, [r2, #_thread_offset_to_basepri]
movs.n r3, #0
movs r3, #0
str r3, [r2, #_thread_offset_to_basepri]
#endif
@ -254,6 +269,19 @@ in_fp_endif:
/* load callee-saved + psp from thread */
add r0, r2, #_thread_offset_to_callee_saved
ldmia r0, {v1-v8, ip}
#elif defined(CONFIG_ARMV7_R)
_thread_irq_disabled:
/* load _kernel into r1 and current k_thread into r2 */
ldr r1, =_kernel
ldr r2, [r1, #_kernel_offset_to_current]
/* addr of callee-saved regs in thread in r0 */
ldr r0, =_thread_offset_to_callee_saved
add r0, r2
/* restore r4-r12 for incoming thread, plus system sp and lr */
ldm r0, {r4-r12,sp,lr}^
msr SPSR_fsxc, r12
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
@ -264,7 +292,9 @@ in_fp_endif:
msr PSPLIM, r0
#endif /* CONFIG_BUILTIN_STACK_GUARD */
#if defined(CONFIG_CPU_CORTEX_M)
msr PSP, ip
#endif
#ifdef CONFIG_BUILTIN_STACK_GUARD
/* r2 contains k_thread */
@ -486,7 +516,80 @@ valid_syscall_id:
bx lr
#endif
#elif defined(CONFIG_ARMV7_R)
SECTION_FUNC(TEXT, __svc)
/*
* Switch to system mode to store r0-r3 to the process stack pointer.
* Save r12 and the lr as we will be swapping in another process and
* returning to a different location.
*/
push {r4, r5}
mov r4, r12
mov r5, lr
cps #MODE_SYS
stmdb sp!, {r0-r5}
cps #MODE_SVC
pop {r4, r5}
/* Get SVC number */
mrs r0, spsr
tst r0, #0x20
ldreq r1, [lr, #-4]
biceq r1, #0xff000000
beq demux
ldr r1, [lr, #-2]
bic r1, #0xff00
/*
* grab service call number:
* 0: context switch
* 1: irq_offload (if configured)
* 2: kernel panic or oops (software generated fatal exception)
* Planned implementation of system calls for memory protection will
* expand this case.
*/
demux:
cmp r1, #_SVC_CALL_CONTEXT_SWITCH
beq _context_switch
cmp r1, #_SVC_CALL_RUNTIME_EXCEPT
beq _oops
#if CONFIG_IRQ_OFFLOAD
push {r0, lr}
blx z_irq_do_offload /* call C routine which executes the offload */
pop {r0, lr}
/* exception return is done in _IntExit() */
mov r0, #RET_FROM_SVC
b _IntExit
#endif
_context_switch:
/* handler mode exit, to PendSV */
push {r0, lr}
bl __pendsv
pop {r0, lr}
mov r0, #RET_FROM_SVC
b _IntExit
_oops:
push {r0, lr}
blx z_do_kernel_oops
pop {r0, lr}
cpsie i
movs pc, lr
GTEXT(cortex_r_svc)
SECTION_FUNC(TEXT, cortex_r_svc)
svc #0
bx lr
#else
#error Unknown ARM architecture
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */