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