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 62OS_NVIC_INT_CTRL = 0xE000ED04 63OS_NVIC_SYSPRI2 = 0xE000ED20 64OS_NVIC_PENDSV_PRI = 0xF0F00000 65OS_NVIC_PENDSVSET = 0x10000000 66OS_TSK_RUNNING = 0x0080 67 68OS_INT_HIGHEST_LEVEL = 0x80 69OS_INT_LOWEST_LEVEL = 0x00 70 71OS_EXC_RETURN_TM_MSP = 0xFFFFFFF9 72 73@exc return flag 74OS_FPU_SAVE_FLAG = 0x10 75OS_SP_SELECT_FLAG = 0x04 76 77@hardware push SP len 78OS_FPU_PUSH_SP_AUTO = 104 79OS_NORMAL_PUSH_SP_AUTO = 32 80 81@switch flag 82OS_SVC_TSK_SWICH = 1 83OS_SVC_VI2TASK = 2 84 85OS_FLG_BGD_ACTIVE = 0x0002 86 87OS_FLG_SYS_ACTIVE = 0x0010 88 89OS_FLG_TSK_REQ = 0x1000 90 91OS_FLG_TSK_SWHK = 0x2000 92 93OS_VI_XPSR = 0x01000000 94 95 .section .text, "ax" 96 .thumb 97 .syntax unified 98 99OsFirstTimeSwitch: 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 108FirstTaskSwtich: 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 153PRT_HwiLock: 154 MRS R0, BASEPRI 155 MOV R1, #OS_INT_HIGHEST_LEVEL 156 MSR BASEPRI, R1 157 BX LR 158 159PRT_HwiUnLock: 160 MRS R0, BASEPRI 161 MOV R1, #OS_INT_LOWEST_LEVEL 162 MSR BASEPRI, R1 163 BX LR 164 165PRT_HwiRestore: 166 MSR BASEPRI, R0 167 BX LR 168 169OsIntNumGet: 170 MRS R0, IPSR 171 BX LR 172 173OsTaskSwitch: 174 SVC #OS_SVC_TSK_SWICH 175 BX LR 176 177OsHwiSwitch: 178 LDR R0, =OS_NVIC_INT_CTRL 179 LDR R1, =OS_NVIC_PENDSVSET 180 STR R1, [R0] 181 BX LR 182 183OsSvchandler: 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 208OsPendSv: 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 222OsGoViDispatch: 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 236OsViSwitchRet: 237 SVC #OS_SVC_VI2TASK 238 B . 239 240OsVi2Task: 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 248OsTaskContexSave: 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 271OsRestoreGeneralR: 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 289OsTaskSwtich: 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 304OsTaskLoad: 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 314OsNotLoadFloat: 315 MSR PSP, R1 316 317OsTaskEnd: 318 MSR BASEPRI, R12 319 @auto restore R0-R3,R12,lr,pc,xpsr 320 BX LR 321 322OsTaskSwtichHook: 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