1/* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 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.thumb 35.fpu fpv5-d16 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 R0, MSP 159 MRSNE R0, PSP 160 LDR R1, [R0,#24] 161 LDRB R0, [R1,#-2] 162 MOV R1, #0 163 B osExcDispatch 164 .fnend 165 166 .type HalExcBusFault, %function 167 .global HalExcBusFault 168HalExcBusFault: 169 .fnstart 170 .cantunwind 171 LDR R0, =OS_NVIC_FSR 172 LDR R0, [R0] 173 174 TST R0, #0x8000 // BFARVALID 175 BEQ _ExcBusNoADDR 176 LDR R1, =OS_NVIC_BFAR 177 LDR R1, [R1] 178 MOV R12, #FLAG_ADDR_VALID 179 AND R0, R0, #0x1F00 180 181 B osExcCommonBMU 182 .fnend 183 184 .type _ExcBusNoADDR, %function 185 .global _ExcBusNoADDR 186_ExcBusNoADDR: 187 .fnstart 188 .cantunwind 189 MOV R12,#0 190 B osExcCommonBMU 191 .fnend 192 193 .type HalExcMemFault, %function 194 .global HalExcMemFault 195HalExcMemFault: 196 .fnstart 197 .cantunwind 198 LDR R0, =OS_NVIC_FSR 199 LDR R0, [R0] 200 201 TST R0, #0x80 // MMARVALID 202 BEQ _ExcMemNoADDR 203 LDR R1, =OS_NVIC_MMAR 204 LDR R1, [R1] 205 MOV R12, #FLAG_ADDR_VALID 206 AND R0, R0, #0x1B 207 208 B osExcCommonBMU 209 .fnend 210 211 .type _ExcMemNoADDR, %function 212 .global _ExcMemNoADDR 213_ExcMemNoADDR: 214 .fnstart 215 .cantunwind 216 MOV R12,#0 217 B osExcCommonBMU 218 .fnend 219 220 .type HalExcUsageFault, %function 221 .global HalExcUsageFault 222HalExcUsageFault: 223 .fnstart 224 .cantunwind 225 LDR R0, =OS_NVIC_FSR 226 LDR R0, [R0] 227 228 MOVW R1, #0x030F 229 LSL R1, R1, #16 230 AND R0, R0, R1 231 MOV R12, #0 232 233 .fnend 234 235 .type osExcCommonBMU, %function 236 .global osExcCommonBMU 237osExcCommonBMU: 238 .fnstart 239 .cantunwind 240 CLZ R0, R0 241 LDR R3, =g_uwExcTbl 242 ADD R3, R3, R0 243 LDRB R0, [R3] 244 ORR R0, R0, R12 245 .fnend 246// R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid), R1 -- EXCADDR 247 248 .type osExcDispatch, %function 249 .global osExcDispatch 250osExcDispatch: 251 .fnstart 252 .cantunwind 253 LDR R2, =OS_NVIC_ACT_BASE 254 MOV R12, #8 // R12 is hwi check loop counter 255 .fnend 256 257 .type _hwiActiveCheck, %function 258 .global _hwiActiveCheck 259_hwiActiveCheck: 260 .fnstart 261 .cantunwind 262 LDR R3, [R2] // R3 store active hwi register when exc 263 CMP R3, #0 264 BEQ _hwiActiveCheckNext 265 266 // exc occurred in IRQ 267 ORR R0, R0, #FLAG_HWI_ACTIVE 268 RBIT R2, R3 269 CLZ R2, R2 270 AND R12, R12, #1 271 ADD R2, R2, R12, LSL #5 // calculate R2 (hwi number) as pid 272 .fnend 273 274 .type _ExcInMSP, %function 275 .global _ExcInMSP 276_ExcInMSP: 277 .fnstart 278 .cantunwind 279 CMP LR, #0xFFFFFFE9 280 BNE _NoFloatInMsp 281 ADD R3, R13, #104 282 PUSH {R3} 283 MRS R12, PRIMASK // store message-->exc: disable int? 284 PUSH {R4-R12} // store message-->exc: {R4-R12} 285 VPUSH {D8-D15} 286 B _handleEntry 287 .fnend 288 289 .type _NoFloatInMsp, %function 290 .global _NoFloatInMsp 291_NoFloatInMsp: 292 .fnstart 293 .cantunwind 294 ADD R3, R13, #32 295 PUSH {R3} // save IRQ SP // store message-->exc: MSP(R13) 296 297 MRS R12, PRIMASK // store message-->exc: disable int? 298 PUSH {R4-R12} // store message-->exc: {R4-R12} 299 ORR R0, R0, #FLAG_NO_FLOAT 300 B _handleEntry 301 .fnend 302 303 .type _hwiActiveCheckNext, %function 304 .global _hwiActiveCheckNext 305_hwiActiveCheckNext: 306 .fnstart 307 .cantunwind 308 ADD R2, R2, #4 // next NVIC ACT ADDR 309 SUBS R12, R12, #1 310 BNE _hwiActiveCheck 311 312 /*NMI interrupt excption*/ 313 LDR R2, =OS_NVIC_SHCSRS 314 LDRH R2,[R2] 315 LDR R3,=OS_NVIC_SHCSR_MASK 316 AND R2, R2,R3 317 CMP R2,#0 318 BNE _ExcInMSP 319 // exc occurred in Task or Init or exc 320 // reserved for register info from task stack 321 322 LDR R2, =g_taskScheduled 323 LDR R2, [R2] 324 TST R2, #1 // OS_FLG_BGD_ACTIVE 325 BEQ _ExcInMSP // if exc occurred in Init then branch 326 327 328 CMP LR, #0xFFFFFFED //auto push floating registers 329 BNE _NoFloatInPsp 330 331 // exc occurred in Task 332 MOV R2, R13 333 SUB R13, #96 // add 8 Bytes reg(for STMFD) 334 335 MRS R3, PSP 336 ADD R12, R3, #104 337 PUSH {R12} // save task SP 338 339 MRS R12, PRIMASK 340 PUSH {R4-R12} 341 VPUSH {D8-D15} 342 343 // copy auto saved task register 344 345 LDMFD R3!, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) 346 VLDMIA R3!, {D8-D15} 347 VSTMDB R2!, {D8-D15} 348 STMFD R2!, {R4-R11} 349 B _handleEntry 350 .fnend 351 352 .type _NoFloatInPsp, %function 353 .global _NoFloatInPsp 354_NoFloatInPsp: 355 .fnstart 356 .cantunwind 357 MOV R2, R13 // no auto push floating registers 358 SUB R13, #32 // add 8 Bytes reg(for STMFD) 359 360 MRS R3, PSP 361 ADD R12, R3, #32 362 PUSH {R12} // save task SP 363 364 MRS R12, PRIMASK 365 PUSH {R4-R12} 366 367 LDMFD R3, {R4-R11} // R4-R11 store PSP reg(auto push when exc in task) 368 STMFD R2!, {R4-R11} 369 ORR R0, R0, #FLAG_NO_FLOAT 370 .fnend 371 372 .type _handleEntry, %function 373 .global _handleEntry 374_handleEntry: 375 .fnstart 376 .cantunwind 377 MOV R3, R13 // R13:the 4th param 378 CPSID I 379 CPSID F 380 B HalExcHandleEntry 381 382 NOP 383 .fnend 384 385