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