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