1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32.syntax unified 33.arch armv7e-m 34.fpu fpv4-sp-d16 35.thumb 36.section .text 37 38 39 .global HalExcNMI 40 .global HalExcHardFault 41 .global HalExcMemFault 42 .global HalExcBusFault 43 .global HalExcUsageFault 44 .global HalExcSvcCall 45 46 .extern HalExcHandleEntry 47 .extern g_uwExcTbl 48 .extern g_taskScheduled 49 50.equ OS_FLG_BGD_ACTIVE, 0x0002 51 52.equ OS_EXC_CAUSE_NMI, 16 53.equ OS_EXC_CAUSE_HARDFAULT, 17 54 55.equ HF_DEBUGEVT, 20 56.equ HF_VECTBL, 21 57 58.equ FLAG_ADDR_VALID, 0x10000 59.equ FLAG_HWI_ACTIVE, 0x20000 60.equ FLAG_NO_FLOAT, 0x10000000 61 62.equ OS_NVIC_FSR, 0xE000ED28 //include BusFault/MemFault/UsageFault State Register 63.equ OS_NVIC_HFSR, 0xE000ED2C //HardFault State Register 64.equ OS_NVIC_BFAR, 0xE000ED38 65.equ OS_NVIC_MMAR, 0xE000ED34 66.equ OS_NVIC_ACT_BASE, 0xE000E300 67.equ OS_NVIC_SHCSRS, 0xE000ED24 68.equ OS_NVIC_SHCSR_MASK, 0xC00 69 70 .type HalExcNMI, %function 71 .global HalExcNMI 72HalExcNMI: 73 .fnstart 74 .cantunwind 75 MOV R0, #OS_EXC_CAUSE_NMI 76 MOV R1, #0 77 B osExcDispatch 78 .fnend 79 80 .type HalExcHardFault, %function 81 .global HalExcHardFault 82HalExcHardFault: 83 .fnstart 84 .cantunwind 85 MOV R0, #OS_EXC_CAUSE_HARDFAULT 86 LDR R2, =OS_NVIC_HFSR 87 LDR R2, [R2] 88 89 MOV R1, #HF_DEBUGEVT 90 ORR R0, R0, R1, LSL #0x8 91 TST R2, #0x80000000 92 BNE osExcDispatch // DEBUGEVT 93 94 AND R0, R0 , #0x000000FF 95 MOV R1, #HF_VECTBL 96 ORR R0, R0, R1, LSL #0x8 97 TST R2, #0x00000002 98 BNE osExcDispatch // VECTBL 99 100 //if not DEBUGEVT and VECTBL then is FORCED 101 AND R0, R0, #0x000000FF 102 103 LDR R2, =OS_NVIC_FSR 104 LDR R2, [R2] 105 106 TST R2, #0x8000 // BFARVALID 107 BNE _HFBusFault // BusFault 108 109 TST R2, #0x80 // MMARVALID 110 BNE _HFMemFault // MemFault 111 112 MOV R12,#0 113 B osHFExcCommonBMU 114 .fnend 115 116 .type _HFBusFault, %function 117 118_HFBusFault: 119 .fnstart 120 .cantunwind 121 LDR R1, =OS_NVIC_BFAR 122 LDR R1, [R1] 123 MOV R12, #FLAG_ADDR_VALID 124 B osHFExcCommonBMU 125 .fnend 126 127 .type _HFMemFault, %function 128 129_HFMemFault: 130 .fnstart 131 .cantunwind 132 LDR R1, =OS_NVIC_MMAR 133 LDR R1, [R1] 134 MOV R12, #FLAG_ADDR_VALID 135 .fnend 136 137 .type osHFExcCommonBMU, %function 138 .global osHFExcCommonBMU 139osHFExcCommonBMU: 140 .fnstart 141 .cantunwind 142 CLZ R2, R2 143 LDR R3, =g_uwExcTbl 144 ADD R3, R3, R2 145 LDRB R2, [R3] 146 ORR R0, R0, R2, LSL #0x8 147 ORR R0, R0 ,R12 148 B osExcDispatch 149 .fnend 150 151 .type HalExcSvcCall, %function 152 .global HalExcSvcCall 153HalExcSvcCall: 154 .fnstart 155 .cantunwind 156 TST LR, #0x4 157 ITE EQ 158 MRSEQ R1, MSP 159 BNE _svcCallFromPsp 160 B _svcCall 161_svcCallFromPsp: 162#ifdef LOSCFG_SECURE 163 PUSH {R0-R12, LR} 164 MOV R0, SP 165 CPSIE I 166 BL OsSyscallHandle 167 CPSID I 168 MRS R12, PSP 169 STM R12, {R0-R1} 170 POP {R0-R12, LR} 171 BX LR 172#endif 173 MRS R1, PSP 174_svcCall: 175 LDR R0, [R1,#24] 176 LDRB R0, [R0,#-2] 177 MOV R1, #0 178 B osExcDispatch 179 .fnend 180 181 .type HalExcBusFault, %function 182 .global HalExcBusFault 183HalExcBusFault: 184 .fnstart 185 .cantunwind 186 LDR R0, =OS_NVIC_FSR 187 LDR R0, [R0] 188 189 TST R0, #0x8000 // BFARVALID 190 BEQ _ExcBusNoADDR 191 LDR R1, =OS_NVIC_BFAR 192 LDR R1, [R1] 193 MOV R12, #FLAG_ADDR_VALID 194 AND R0, R0, #0x1F00 195 196 B osExcCommonBMU 197 .fnend 198 199 .type _ExcBusNoADDR, %function 200 .global _ExcBusNoADDR 201_ExcBusNoADDR: 202 .fnstart 203 .cantunwind 204 MOV R12,#0 205 B osExcCommonBMU 206 .fnend 207 208 .type HalExcMemFault, %function 209 .global HalExcMemFault 210HalExcMemFault: 211 .fnstart 212 .cantunwind 213 LDR R0, =OS_NVIC_FSR 214 LDR R0, [R0] 215 216 TST R0, #0x80 // MMARVALID 217 BEQ _ExcMemNoADDR 218 LDR R1, =OS_NVIC_MMAR 219 LDR R1, [R1] 220 MOV R12, #FLAG_ADDR_VALID 221 AND R0, R0, #0x1B 222 223 B osExcCommonBMU 224 .fnend 225 226 .type _ExcMemNoADDR, %function 227 .global _ExcMemNoADDR 228_ExcMemNoADDR: 229 .fnstart 230 .cantunwind 231 MOV R12,#0 232 B osExcCommonBMU 233 .fnend 234 235 .type HalExcUsageFault, %function 236 .global HalExcUsageFault 237HalExcUsageFault: 238 .fnstart 239 .cantunwind 240 LDR R0, =OS_NVIC_FSR 241 LDR R0, [R0] 242 243 MOVW R1, #0x030F 244 LSL R1, R1, #16 245 AND R0, R0, R1 246 MOV R12, #0 247 248 .fnend 249 250 .type osExcCommonBMU, %function 251 .global osExcCommonBMU 252osExcCommonBMU: 253 .fnstart 254 .cantunwind 255 CLZ R0, R0 256 LDR R3, =g_uwExcTbl 257 ADD R3, R3, R0 258 LDRB R0, [R3] 259 ORR R0, R0, R12 260 .fnend 261// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR 262 263 .type osExcDispatch, %function 264 .global osExcDispatch 265osExcDispatch: 266 .fnstart 267 .cantunwind 268 LDR R2, =OS_NVIC_ACT_BASE 269 MOV R12, #8 // R12 is hwi check loop counter 270 .fnend 271 272 .type _hwiActiveCheck, %function 273 .global _hwiActiveCheck 274_hwiActiveCheck: 275 .fnstart 276 .cantunwind 277 LDR R3, [R2] // R3 store active hwi register when exc 278 CMP R3, #0 279 BEQ _hwiActiveCheckNext 280 281 // exc occurred in IRQ 282 ORR R0, R0, #FLAG_HWI_ACTIVE 283 RBIT R2, R3 284 CLZ R2, R2 285 AND R12, R12, #1 286 ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as pid 287 .fnend 288 289 .type _ExcInMSP, %function 290 .global _ExcInMSP 291_ExcInMSP: 292 .fnstart 293 .cantunwind 294 CMP LR, #0xFFFFFFE9 295 BNE _NoFloatInMsp 296 ADD R3, R13, #104 297 PUSH {R3} 298 MRS R12, PRIMASK // store message-->exc: disable int? 299 PUSH {R4-R12} // store message-->exc: {R4-R12} 300 VPUSH {D8-D15} // FPU 301 B _handleEntry 302 .fnend 303 304 .type _NoFloatInMsp, %function 305 .global _NoFloatInMsp 306_NoFloatInMsp: 307 .fnstart 308 .cantunwind 309 ADD R3, R13, #32 310 PUSH {R3} // store message-->exc: MSP(R13) 311 312 MRS R12, PRIMASK // store message-->exc: disable int? 313 PUSH {R4-R12} // store message-->exc: {R4-R12} 314 ORR R0, R0, #FLAG_NO_FLOAT 315 B _handleEntry 316 .fnend 317 318 .type _hwiActiveCheckNext, %function 319 .global _hwiActiveCheckNext 320_hwiActiveCheckNext: 321 .fnstart 322 .cantunwind 323 ADD R2, R2, #4 // next NVIC ACT ADDR 324 SUBS R12, R12, #1 325 BNE _hwiActiveCheck 326 327 /*NMI interrupt excption*/ 328 LDR R2, =OS_NVIC_SHCSRS 329 LDRH R2,[R2] 330 LDR R3,=OS_NVIC_SHCSR_MASK 331 AND R2, R2,R3 332 CMP R2,#0 333 BNE _ExcInMSP 334 // exc occurred in Task or Init or exc 335 // reserved for register info from task stack 336 337 LDR R2, =g_taskScheduled 338 LDR R2, [R2] 339 TST R2, #1 // OS_FLG_BGD_ACTIVE 340 BEQ _ExcInMSP // if exc occurred in Init then branch 341 342 343 CMP LR, #0xFFFFFFED //auto push floating registers 344 BNE _NoFloatInPsp 345 346 // exc occurred in Task 347 MOV R2, R13 348 SUB R13, #96 // add 8 Bytes reg(for STMFD) 349 350 MRS R3, PSP 351 ADD R12, R3, #104 352 PUSH {R12} // save task SP 353 354 MRS R12, PRIMASK 355 PUSH {R4-R12} 356 VPUSH {D8-D15} // FPU 357 358 // copy auto saved task register 359 360 LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) 361 VLDMIA R3!, {D8-D15} // FPU 362 VSTMDB R2!, {D8-D15} // FPU 363 STMFD R2!, {R4-R11} 364 B _handleEntry 365 .fnend 366 367 .type _NoFloatInPsp, %function 368 .global _NoFloatInPsp 369_NoFloatInPsp: 370 .fnstart 371 .cantunwind 372 MOV R2, R13 // no auto push floating registers 373 SUB R13, #32 // add 8 Bytes reg(for STMFD) 374 375 MRS R3, PSP 376 ADD R12, R3, #32 377 PUSH {R12} // save task SP 378 379 MRS R12, PRIMASK 380 PUSH {R4-R12} 381 382 LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) 383 STMFD R2!, {R4-R11} 384 ORR R0, R0, #FLAG_NO_FLOAT 385 .fnend 386 387 .type _handleEntry, %function 388 .global _handleEntry 389_handleEntry: 390 .fnstart 391 .cantunwind 392 MOV R3, R13 // R13:the 4th param 393 CPSID I 394 CPSID F 395 B HalExcHandleEntry 396 397 NOP 398 .fnend 399