xref: /nrf52832-nimble/rt-thread/libcpu/arm/arm926/context_rvds.S (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero;/*
2*10465441SEvalZero; * Copyright (c) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero; *
4*10465441SEvalZero; * SPDX-License-Identifier: Apache-2.0
5*10465441SEvalZero; *
6*10465441SEvalZero; * Change Logs:
7*10465441SEvalZero; * Date           Author       Notes
8*10465441SEvalZero; * 2011-08-14     weety    copy from mini2440
9*10465441SEvalZero; */
10*10465441SEvalZero
11*10465441SEvalZeroNOINT    EQU        0XC0    ; disable interrupt in psr
12*10465441SEvalZero
13*10465441SEvalZero    AREA |.TEXT|, CODE, READONLY, ALIGN=2
14*10465441SEvalZero    ARM
15*10465441SEvalZero    REQUIRE8
16*10465441SEvalZero    PRESERVE8
17*10465441SEvalZero
18*10465441SEvalZero;/*
19*10465441SEvalZero; * rt_base_t rt_hw_interrupt_disable();
20*10465441SEvalZero; */
21*10465441SEvalZerort_hw_interrupt_disable    PROC
22*10465441SEvalZero    EXPORT rt_hw_interrupt_disable
23*10465441SEvalZero    MRS     R0, CPSR
24*10465441SEvalZero    ORR     R1, R0, #NOINT
25*10465441SEvalZero    MSR     CPSR_C, R1
26*10465441SEvalZero    BX      LR
27*10465441SEvalZero    ENDP
28*10465441SEvalZero
29*10465441SEvalZero;/*
30*10465441SEvalZero; * void rt_hw_interrupt_enable(rt_base_t level);
31*10465441SEvalZero; */
32*10465441SEvalZerort_hw_interrupt_enable    proc
33*10465441SEvalZero    export rt_hw_interrupt_enable
34*10465441SEvalZero    msr     cpsr_c, r0
35*10465441SEvalZero    bx      lr
36*10465441SEvalZero    endp
37*10465441SEvalZero
38*10465441SEvalZero;/*
39*10465441SEvalZero; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
40*10465441SEvalZero; * r0 --> from
41*10465441SEvalZero; * r1 --> to
42*10465441SEvalZero; */
43*10465441SEvalZerort_hw_context_switch    proc
44*10465441SEvalZero    export rt_hw_context_switch
45*10465441SEvalZero    stmfd   sp!, {lr}           ; push pc (lr should be pushed in place of pc)
46*10465441SEvalZero    stmfd   sp!, {r0-r12, lr}       ; push lr & register file
47*10465441SEvalZero    mrs     r4, cpsr
48*10465441SEvalZero    stmfd   sp!, {r4}               ; push cpsr
49*10465441SEvalZero    str     sp, [r0]                ; store sp in preempted tasks tcb
50*10465441SEvalZero    ldr     sp, [r1]                ; get new task stack pointer
51*10465441SEvalZero    ldmfd   sp!, {r4}               ; pop new task spsr
52*10465441SEvalZero    msr     spsr_cxsf, r4
53*10465441SEvalZero    ldmfd   sp!, {r0-r12, lr, pc}^  ; pop new task r0-r12, lr & pc
54*10465441SEvalZero    endp
55*10465441SEvalZero
56*10465441SEvalZero;/*
57*10465441SEvalZero; * void rt_hw_context_switch_to(rt_uint32 to);
58*10465441SEvalZero; * r0 --> to
59*10465441SEvalZero; */
60*10465441SEvalZerort_hw_context_switch_to    proc
61*10465441SEvalZero    export rt_hw_context_switch_to
62*10465441SEvalZero    ldr     sp, [r0]                ; get new task stack pointer
63*10465441SEvalZero    ldmfd   sp!, {r4}               ; pop new task spsr
64*10465441SEvalZero    msr     spsr_cxsf, r4
65*10465441SEvalZero    ldmfd   sp!, {r0-r12, lr, pc}^   ; pop new task r0-r12, lr & pc
66*10465441SEvalZero    endp
67*10465441SEvalZero
68*10465441SEvalZero;/*
69*10465441SEvalZero; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
70*10465441SEvalZero; */
71*10465441SEvalZero    import rt_thread_switch_interrupt_flag
72*10465441SEvalZero    import rt_interrupt_from_thread
73*10465441SEvalZero    import rt_interrupt_to_thread
74*10465441SEvalZero
75*10465441SEvalZerort_hw_context_switch_interrupt    proc
76*10465441SEvalZero    export rt_hw_context_switch_interrupt
77*10465441SEvalZero    ldr     r2, =rt_thread_switch_interrupt_flag
78*10465441SEvalZero    ldr     r3, [r2]
79*10465441SEvalZero    cmp     r3, #1
80*10465441SEvalZero    beq     _reswitch
81*10465441SEvalZero    mov     r3, #1                          ; set flag to 1
82*10465441SEvalZero    str     r3, [r2]
83*10465441SEvalZero    ldr     r2, =rt_interrupt_from_thread   ; set rt_interrupt_from_thread
84*10465441SEvalZero    str     r0, [r2]
85*10465441SEvalZero_reswitch
86*10465441SEvalZero    ldr     r2, =rt_interrupt_to_thread     ; set rt_interrupt_to_thread
87*10465441SEvalZero    str     r1, [r2]
88*10465441SEvalZero    bx      lr
89*10465441SEvalZero    endp
90*10465441SEvalZero
91*10465441SEvalZero    end
92