• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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