xref: /nrf52832-nimble/rt-thread/libcpu/arm/dm36x/context_gcc.S (revision 042d53a763ad75cb1465103098bb88c245d95138)
1/*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date           Author       Notes
8 * 2011-01-13     weety
9 */
10
11/*!
12 * \addtogroup DM36X
13 */
14/*@{*/
15
16#define NOINT          0xc0
17
18
19/*
20 * rt_base_t rt_hw_interrupt_disable();
21 */
22.globl rt_hw_interrupt_disable
23rt_hw_interrupt_disable:
24    mrs r0, cpsr
25    orr r1, r0, #NOINT
26    msr cpsr_c, r1
27    bx  lr
28
29/*
30 * void rt_hw_interrupt_enable(rt_base_t level);
31 */
32.globl rt_hw_interrupt_enable
33rt_hw_interrupt_enable:
34    msr cpsr, r0
35    bx  lr
36
37/*
38 * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
39 * r0 --> from
40 * r1 --> to
41 */
42.globl rt_hw_context_switch
43rt_hw_context_switch:
44    stmfd   sp!, {lr}       @ push pc (lr should be pushed in place of PC)
45    stmfd   sp!, {r0-r12, lr}   @ push lr & register file
46
47    mrs r4, cpsr
48    tst lr, #0x01
49    orrne r4, r4, #0x20     @ it's thumb code
50
51    stmfd sp!, {r4}         @ push cpsr
52
53    str sp, [r0]            @ store sp in preempted tasks TCB
54    ldr sp, [r1]            @ get new task stack pointer
55
56    ldmfd sp!, {r4}         @ pop new task cpsr to spsr
57    msr spsr_cxsf, r4
58_do_switch:
59    ldmfd sp!, {r0-r12, lr, pc}^  @ pop new task r0-r12, lr & pc, copy spsr to cpsr
60
61/*
62 * void rt_hw_context_switch_to(rt_uint32 to);
63 * r0 --> to
64 */
65.globl rt_hw_context_switch_to
66rt_hw_context_switch_to:
67    ldr sp, [r0]            @ get new task stack pointer
68
69    ldmfd sp!, {r4}         @ pop new task spsr
70    msr spsr_cxsf, r4
71
72    bic r4, r4, #0x20       @ must be ARM mode
73    msr cpsr_cxsf, r4
74    ldmfd sp!, {r0-r12, lr, pc}^   @ pop new task r0-r12, lr & pc
75
76/*
77 * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
78 */
79.globl rt_thread_switch_interrupt_flag
80.globl rt_interrupt_from_thread
81.globl rt_interrupt_to_thread
82.globl rt_hw_context_switch_interrupt
83rt_hw_context_switch_interrupt:
84    ldr r2, =rt_thread_switch_interrupt_flag
85    ldr r3, [r2]
86    cmp r3, #1
87    beq _reswitch
88    mov r3, #1              @ set rt_thread_switch_interrupt_flag to 1
89    str r3, [r2]
90    ldr r2, =rt_interrupt_from_thread   @ set rt_interrupt_from_thread
91    str r0, [r2]
92_reswitch:
93    ldr r2, =rt_interrupt_to_thread     @ set rt_interrupt_to_thread
94    str r1, [r2]
95    bx  lr
96