xref: /nrf52832-nimble/rt-thread/components/lwp/arch/arm/cortex-m7/lwp_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
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 * 2018-10-30     heyuanjie    first version
9 */
10
11.cpu cortex-m7
12.syntax unified
13.thumb
14.text
15
16/*
17 * void* lwp_get_sys_api(rt_uint32_t number);
18 */
19.global lwp_get_sys_api
20.global lwp_get_kernel_sp
21.global lwp_set_kernel_sp
22
23
24/*
25 * void lwp_user_entry(args, text, data);
26 */
27.global lwp_user_entry
28.type lwp_user_entry, % function
29lwp_user_entry:
30    PUSH    {R0-R3}             @; push text&data addr.
31
32    MOV     R0, SP              @; v1 = SP
33    BL      lwp_set_kernel_sp   @; lwp_set_kernel_sp(v1)
34
35    @; set CPU to user-thread mode.
36    MRS     R2, CONTROL
37    ORR     R2, R2, #0x03       @; use PSP, user-thread mode.
38    MSR     CONTROL, R2
39
40    POP     {R0-R3}             @; pop app address to R1.
41    @; set data address.
42    MOV     R9, R2
43
44    @; run app, only Thumb-mode.
45    ORR     R1, R1, #0x01
46    BX      R1
47
48/*
49 * void SVC_Handler(void);
50 */
51.global SVC_Handler
52.type SVC_Handler, % function
53SVC_Handler:
54    PUSH    {LR}
55
56    @; get user SP.
57    TST     LR, #0x4
58    ITE     EQ
59    MRSEQ   R1, MSP
60    MRSNE   R1, PSP
61    PUSH    {R1}           @; push app SP.
62
63    @; get SVC number.
64    mov     R0, R7
65
66    @; get kernel system API
67    BL      lwp_get_sys_api
68
69    PUSH    {R0}            @; push api
70
71    @; get kernel SP to R0.
72    BL lwp_get_kernel_sp
73
74    POP     {R2}             @; pop api to R2.
75    POP     {R1}             @; pop app SP to R1.
76
77    stmfd     r0!, {r1}      @; save app SP to kernel SP
78
79    @;push app parm5~6 to kernel SP
80    STMFD   R0!,  {R4 - R5}
81    @; copy R1(app SP) to R0(kernel SP).
82    push {r8-r11}
83    LDMFD   R1,   {R4 - R11}     @; pop exception_stack_frame to r4 - r11 register
84    STMFD   R0!,  {R4 - R11}     @; push exception_stack_frame to server SP.
85    pop {r8-r11}
86
87    LDR     R3, =svc_exit
88    STR     R3, [R0, #20]       @; update LR
89    STR     R2, [R0, #24]       @; update api to PC
90    MSR     PSP, R0             @; update SP, API is executed with kernel SP
91
92    @; set to thread-privilege mode.
93    MRS     R3, CONTROL
94    BIC     R3, R3, #0x01
95    ORR     R3, R3, #0x02
96    MSR     CONTROL, R3
97
98    POP     {LR}                @; 0xFFFFFFED
99    ORR     LR, LR, #0x10
100    BX      LR
101/*
102* void svc_exit(void);
103*/
104.global svc_exit
105.type svc_exit, % function
106svc_exit:
107    @; get user SP.
108    PUSH    {R0}                    @; push result to SP.
109    BL      lwp_get_kernel_sp
110    ldr     r3, [r0, #-4]
111    pop {r0}
112
113    ldr     lr, [r3, #20]
114    ldr     r1, [r3, #24]           @; load pc
115    add     r3, #32                 @; exception_stack_frame size
116    MSR     PSP, R3                 @; restore app stack pointer
117    @; restore to PSP & thread-unprivilege mode.
118    MRS     R2, CONTROL
119    ORR     R2, R2, #0x03
120    MSR     CONTROL, R2
121
122    @; return to lwp.
123    ORR     R1, R1, #0x01           @; only Thumb-mode.
124    BX      R1                      @; return to user app.
125