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