1 @/*
2 @ * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 @ *
4 @ * UniProton is licensed under Mulan PSL v2.
5 @ * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 @ * You may obtain a copy of Mulan PSL v2 at:
7 @ *          http://license.coscl.org.cn/MulanPSL2
8 @ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 @ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 @ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 @ * See the Mulan PSL v2 for more details.
12 @ * Create: 2009-07-24
13 @ * Description: thread scheduler
14 @ */
15     .align 8
16 
17     .global  PRT_HwiLock
18     .global  PRT_HwiUnLock
19     .global  PRT_HwiRestore
20     .global  OsFirstTimeSwitch
21     .global  OsTaskSwitch
22     .global  OsHwiSwitch
23     .global  OsPendSv
24     .global  OsIntNumGet
25     .global  OsSvchandler
26     .global  OsRestoreGeneralR
27     .global  OsTaskSwtichHook
28     .global  OsViSwitchRet
29 
30     .type PRT_HwiLock, function
31     .type PRT_HwiUnLock, function
32     .type PRT_HwiRestore, function
33     .type OsFirstTimeSwitch, function
34     .type FirstTaskSwtich,function
35 
36     .type OsIntNumGet, function
37     .type OsTaskSwitch, function
38     .type OsHwiSwitch,function
39     .type OsSvchandler, function
40     .type OsPendSv, function
41     .type OsGoViDispatch,function
42     .type OsViSwitchRet, function
43     .type OsVi2Task,function
44     .type OsTaskContexSave,function
45     .type OsRestoreGeneralR, function
46     .type OsTaskSwtich,function
47     .type OsTaskLoad,function
48     .type OsNotLoadFloat,function
49     .type OsTaskEnd,function
50     .type OsTaskSwtichHook,function
51     .type OsViDispatch,function
52 
53     .extern  g_runningTask
54     .extern  g_highestTask
55     .extern  g_stackEnd
56     .extern  g_uniFlag
57     .extern  OsViDispatch
58     .extern  g_tickNoRespondCnt
59     .extern  g_excTrap
60     .extern  OsTskSwitchHookCaller
61 
62 OS_NVIC_INT_CTRL           = 0xE000ED04
63 OS_NVIC_SYSPRI2            = 0xE000ED20
64 OS_NVIC_PENDSV_PRI         = 0xF0F00000
65 OS_NVIC_PENDSVSET          = 0x10000000
66 OS_TSK_RUNNING             = 0x0080
67 
68 OS_INT_HIGHEST_LEVEL       = 0x80
69 OS_INT_LOWEST_LEVEL        = 0x00
70 
71 OS_EXC_RETURN_TM_MSP       = 0xFFFFFFF9
72 
73 @exc return flag
74 OS_FPU_SAVE_FLAG           = 0x10
75 OS_SP_SELECT_FLAG          = 0x04
76 
77 @hardware push SP len
78 OS_FPU_PUSH_SP_AUTO        = 104
79 OS_NORMAL_PUSH_SP_AUTO     = 32
80 
81 @switch flag
82 OS_SVC_TSK_SWICH           = 1
83 OS_SVC_VI2TASK             = 2
84 
85 OS_FLG_BGD_ACTIVE          = 0x0002
86 
87 OS_FLG_SYS_ACTIVE          = 0x0010
88 
89 OS_FLG_TSK_REQ             = 0x1000
90 
91 OS_FLG_TSK_SWHK            = 0x2000
92 
93 OS_VI_XPSR                 = 0x01000000
94 
95     .section .text, "ax"
96     .thumb
97     .syntax unified
98 
99 OsFirstTimeSwitch:
100     LDR     R4, =OS_NVIC_SYSPRI2
101     LDR     R5, =OS_NVIC_PENDSV_PRI
102     STR     R5, [R4]
103 
104     @ reset MSP
105     LDR     R0, =g_stackEnd
106     MSR     MSP, R0
107 
108 FirstTaskSwtich:
109     @use PSP in thread mode from now
110     MOV     R0, #2
111     MSR     CONTROL, R0
112 
113     @g_uniFlag
114     LDR     R0, =g_uniFlag
115     LDR     R1, [R0]
116     ORR     R1, R1,#OS_FLG_BGD_ACTIVE
117 
118     STR     R1, [R0]
119 
120     @g_runningTask = g_highestTask
121     LDR     R0, =g_highestTask
122     LDR     R0, [R0]
123     LDR     R1, =g_runningTask
124     STR     R0, [R1]
125 
126     @g_runningTask->taskStatus |= OS_TSK_RUNNING
127     LDRH    R1, [R0, #4]
128     ORR     R1, R1, #OS_TSK_RUNNING
129     STRH    R1, [R0, #4]
130 
131     @ get func parameter from stack
132     LDR     R1, [R0]
133     ADD     R1, R1, #40
134     LDR     R5, [R1]
135 
136     @get LR,PC,XPSR from stack
137     ADD     R1, R1, #20
138     LDMFD   R1!, {R2-R4}
139     MSR     PSP, R1
140     MOV     LR, R2
141     MSR     xPSR, R4
142     MOV     R0, R5
143     CPSIE   I
144 
145     BX      R3
146 
147     .align
148 
149     .section .kernel, "ax"
150     .thumb
151     .syntax unified
152 
153 PRT_HwiLock:
154     MRS     R0, BASEPRI
155     MOV     R1, #OS_INT_HIGHEST_LEVEL
156     MSR     BASEPRI, R1
157     BX      LR
158 
159 PRT_HwiUnLock:
160     MRS     R0, BASEPRI
161     MOV     R1, #OS_INT_LOWEST_LEVEL
162     MSR     BASEPRI, R1
163     BX      LR
164 
165 PRT_HwiRestore:
166     MSR     BASEPRI, R0
167     BX      LR
168 
169 OsIntNumGet:
170     MRS     R0, IPSR
171     BX      LR
172 
173 OsTaskSwitch:
174     SVC     #OS_SVC_TSK_SWICH
175     BX      LR
176 
177 OsHwiSwitch:
178     LDR     R0, =OS_NVIC_INT_CTRL
179     LDR     R1, =OS_NVIC_PENDSVSET
180     STR     R1, [R0]
181     BX      LR
182 
183 OsSvchandler:
184     TST     LR, #OS_SP_SELECT_FLAG
185     ITE     EQ
186     MRSEQ   R0, MSP
187     MRSNE   R0, PSP
188 
189     @get pc
190     LDR     R1, [R0,#24]
191 
192     @get svc instruction
193     LDRB    R0, [R1,#-2]
194 
195     CMP     R0, #OS_SVC_TSK_SWICH
196     BEQ     OsPendSv
197 
198     CMP     R0, #OS_SVC_VI2TASK
199     BEQ     OsVi2Task
200 
201     @ excpetion
202     LDR     R1, =g_excTrap
203     LDR     R1, [R1]
204     CMP     R1, #0
205     BXNE    R1
206     B .
207 
208 OsPendSv:
209     MRS     R12, BASEPRI
210     MOV     R2, #OS_INT_HIGHEST_LEVEL
211     MSR     BASEPRI, R2
212 
213     @tick switch
214     LDR     R0, =g_tickNoRespondCnt
215     LDR     R3, [R0]
216     CMP     R3, #0
217     BNE     OsGoViDispatch
218 
219     @task switch
220     B       OsTaskContexSave
221 
222 OsGoViDispatch:
223     push    {R12,LR}
224 
225     @call tick dispatch
226     LDR     R3, =OS_VI_XPSR
227     LDR     R2, =OsViDispatch
228     LDR     R1, =OsViSwitchRet
229     push    {R1-R3}
230     sub     sp,sp,#20
231 
232     @thread mode msp
233     MOV     LR, #OS_EXC_RETURN_TM_MSP
234     BX      LR
235 
236 OsViSwitchRet:
237     SVC     #OS_SVC_VI2TASK
238     B .
239 
240 OsVi2Task:
241     TST     LR, #OS_FPU_SAVE_FLAG
242     ITE     EQ
243     MOVEQ   R2, #OS_FPU_PUSH_SP_AUTO
244     MOVNE   R2, #OS_NORMAL_PUSH_SP_AUTO
245     ADD     SP, SP, R2
246     pop     {R12, LR}
247 
248 OsTaskContexSave:
249     TST     LR, #OS_SP_SELECT_FLAG
250     BEQ     OsTaskEnd
251 
252     @save task context
253     LDR     R0, =g_uniFlag
254     LDR     R1, [R0]
255     MOV     R3, R1
256 
257     BIC     R1, R1, #OS_FLG_TSK_REQ /* g_uniFlag &= ~OS_FLG_TSK_REQ */
258     STR     R1, [R0]
259     TST     R3, #OS_FLG_TSK_REQ
260     BEQ     OsTaskEnd
261 
262     @get PSP
263     MRS     R0, PSP
264 
265     @Is the task using the FPU context? If so, push high vfp registers.
266     TST     LR, #OS_FPU_SAVE_FLAG
267     BNE     OsRestoreGeneralR
268     @store s16-s31
269     VSTMDB  R0!, {S16-S31}
270 
271 OsRestoreGeneralR:
272     @store R4-R11,BASEPRI,EXC_RETURN
273     STMFD   R0!, {R4-R12, LR}
274 
275     @g_runningTask->stackPointer = PSP
276     LDR     R5, =g_runningTask
277     LDR     R6, [R5]
278     STR     R0, [R6]
279 
280     @g_runningTask->taskStatus &= ~OS_TSK_RUNNING
281     LDRH    R1, [R6, #4]
282     BIC     R1, R1, #OS_TSK_RUNNING
283     STRH    R1, [R6, #4]
284 
285     @get new task
286     LDR     R7, =g_highestTask
287     LDR     R7, [R7]
288 
289 OsTaskSwtich:
290     @g_runningTask = g_highestTask
291     STR     R7, [R5]
292 
293     @g_runningTask->taskStatus |= OS_TSK_RUNNING
294     LDRH    R1, [R7, #4]
295     ORR     R1, R1, #OS_TSK_RUNNING
296     STRH    R1, [R7, #4]
297 
298     @task switch hook,dot not change R5 R6 R7
299     LDR     R0, =g_uniFlag
300     LDR     R1, [R0]
301     TST     R1, #OS_FLG_TSK_SWHK
302     BNE     OsTaskSwtichHook
303 
304 OsTaskLoad:
305     @load R4-R11,BASEPRI,EXC_RETURN
306     LDR     R1, [R7]
307     LDMFD   R1!, {R4-R12,LR}
308 
309     TST     LR, #OS_FPU_SAVE_FLAG
310     BNE     OsNotLoadFloat
311     @load s16-s31
312     VLDMIA  R1!, {S16-S31}
313 
314 OsNotLoadFloat:
315     MSR     PSP, R1
316 
317 OsTaskEnd:
318     MSR     BASEPRI, R12
319     @auto restore R0-R3,R12,lr,pc,xpsr
320     BX      LR
321 
322 OsTaskSwtichHook:
323     LDR     R3, =OsTskSwitchHookCaller
324     LDR     R0, [R6, #16]
325     LDR     R1, [R7, #16]
326     LDR     LR, =OsTaskLoad
327     BX      R3
328     .align
329     .end
330