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     PRESERVE8
33     SECTION    .text:CODE(2)
34     THUMB
35 
36     EXPORT  HalExcNMI
37     EXPORT  HalExcHardFault
38     EXPORT  HalExcMemFault
39     EXPORT  HalExcBusFault
40     EXPORT  HalExcUsageFault
41     EXPORT  HalExcSvcCall
42 
43     IMPORT HalExcHandleEntry
44     IMPORT g_uwExcTbl
45     IMPORT g_taskScheduled
46 
47 OS_FLG_BGD_ACTIVE   EQU   0x0002
48 
49 OS_EXC_CAUSE_NMI            EQU   16
50 OS_EXC_CAUSE_HARDFAULT      EQU   17
51 
52 HF_DEBUGEVT     EQU   20
53 HF_VECTBL       EQU   21
54 
55 FLAG_ADDR_VALID             EQU   0x10000
56 FLAG_HWI_ACTIVE             EQU   0x20000
57 FLAG_NO_FLOAT               EQU   0x10000000
58 
59 OS_NVIC_FSR                 EQU   0xE000ED28      ;include BusFault/MemFault/UsageFault State Register
60 OS_NVIC_HFSR                EQU   0xE000ED2C      ;HardFault State Register
61 OS_NVIC_BFAR                EQU   0xE000ED38
62 OS_NVIC_MMAR                EQU   0xE000ED34
63 OS_NVIC_ACT_BASE            EQU   0xE000E300
64 OS_NVIC_SHCSRS              EQU   0xE000ED24
65 OS_NVIC_SHCSR_MASK          EQU   0xC00
66 
67 HalExcNMI
68     MOV  R0, #OS_EXC_CAUSE_NMI
69     MOV  R1, #0
70     B  osExcDispatch
71 
72 HalExcHardFault
73     MOV  R0, #OS_EXC_CAUSE_HARDFAULT
74     LDR  R2, =OS_NVIC_HFSR
75     LDR  R2, [R2]
76 
77     MOV  R1, #HF_DEBUGEVT
78     ORR  R0, R0, R1, LSL #0x8
79     TST  R2, #0x80000000
80     BNE  osExcDispatch     ; DEBUGEVT
81 
82     AND  R0, R0 , #0x000000FF
83     MOV  R1, #HF_VECTBL
84     ORR  R0, R0, R1, LSL #0x8
85     TST  R2, #0x00000002
86     BNE  osExcDispatch     ; VECTBL
87 
88     ;if not DEBUGEVT and VECTBL then is FORCED
89     AND  R0, R0, #0x000000FF
90 
91     LDR  R2, =OS_NVIC_FSR
92     LDR  R2, [R2]
93 
94     TST  R2, #0x8000     ; BFARVALID
95     BNE  _HFBusFault     ; BusFault
96 
97     TST  R2, #0x80       ; MMARVALID
98     BNE  _HFMemFault     ; MemFault
99 
100     MOV  R12,#0
101     B    osHFExcCommonBMU
102 
103 _HFBusFault
104     LDR  R1, =OS_NVIC_BFAR
105     LDR  R1, [R1]
106     MOV  R12, #FLAG_ADDR_VALID
107     B    osHFExcCommonBMU
108 
109 _HFMemFault
110     LDR  R1, =OS_NVIC_MMAR
111     LDR  R1, [R1]
112     MOV  R12, #FLAG_ADDR_VALID
113 
114 osHFExcCommonBMU
115     CLZ  R2, R2
116     LDR  R3, =g_uwExcTbl
117     ADD  R3, R3, R2
118     LDRB R2, [R3]
119     ORR  R0, R0, R2, LSL #0x8
120     ORR  R0, R0 ,R12
121     B    osExcDispatch
122 
123 HalExcSvcCall
124     TST   LR, #0x4
125     ITE   EQ
126     MRSEQ R0, MSP
127     MRSNE R0, PSP
128     LDR   R1, [R0,#24]
129     LDRB  R0, [R1,#-2]
130     MOV   R1, #0
131     B     osExcDispatch
132 
133 HalExcBusFault
134     LDR  R0, =OS_NVIC_FSR
135     LDR  R0, [R0]
136 
137     TST  R0, #0x8000 ; BFARVALID
138     BEQ  _ExcBusNoADDR
139     LDR  R1, =OS_NVIC_BFAR
140     LDR  R1, [R1]
141     MOV  R12, #FLAG_ADDR_VALID
142     AND  R0, R0, #0x1F00
143 
144     B    osExcCommonBMU
145 
146 _ExcBusNoADDR
147     MOV  R12,#0
148     B    osExcCommonBMU
149 
150 HalExcMemFault
151     LDR  R0, =OS_NVIC_FSR
152     LDR  R0, [R0]
153 
154     TST  R0, #0x80 ; MMARVALID
155     BEQ  _ExcMemNoADDR
156     LDR  R1, =OS_NVIC_MMAR
157     LDR  R1, [R1]
158     MOV  R12, #FLAG_ADDR_VALID
159     AND  R0, R0, #0x1B
160 
161     B    osExcCommonBMU
162 
163 _ExcMemNoADDR
164     MOV  R12,#0
165     B    osExcCommonBMU
166 
167 HalExcUsageFault
168     LDR  R0, =OS_NVIC_FSR
169     LDR  R0, [R0]
170 
171     MOV  R1, #0x030F
172     LSL  R1, R1, #16
173     AND  R0, R0, R1
174     MOV  R12, #0
175 
176 osExcCommonBMU
177     CLZ  R0, R0
178     LDR  R3, =g_uwExcTbl
179     ADD  R3, R3, R0
180     LDRB R0, [R3]
181     ORR  R0, R0, R12
182 
183 ; R0 -- EXCCAUSE(bit 16 is 1 if EXCADDR valid),  R1 -- EXCADDR
184 osExcDispatch
185     LDR   R2, =OS_NVIC_ACT_BASE
186     MOV   R12, #8                       ; R12 is hwi check loop counter
187 
188 _hwiActiveCheck
189     LDR   R3, [R2]                      ; R3 store active hwi register when exc
190     CMP   R3, #0
191     BEQ   _hwiActiveCheckNext
192 
193     ; exc occurred in IRQ
194     ORR   R0, R0, #FLAG_HWI_ACTIVE
195     RBIT  R2, R3
196     CLZ   R2, R2
197     AND   R12, R12, #1
198     ADD   R2, R2, R12, LSL #5               ; calculate R2 (hwi number) as pid
199 
200 _ExcInMSP
201     CMP   LR, #0xFFFFFFE9
202     BNE   _NoFloatInMsp
203     ADD   R3, R13, #104
204     PUSH  {R3}
205     MRS   R12, PRIMASK                  ; store message-->exc: disable int?
206     PUSH {R4-R12}                       ; store message-->exc: {R4-R12}
207     VPUSH {D8-D15}
208     B     _handleEntry
209 
210 _NoFloatInMsp
211     ADD   R3, R13, #32
212     PUSH  {R3} ; save IRQ SP            ; store message-->exc: MSP(R13)
213 
214     MRS   R12, PRIMASK                  ; store message-->exc: disable int?
215     PUSH {R4-R12}                       ; store message-->exc: {R4-R12}
216     ORR   R0, R0, #FLAG_NO_FLOAT
217     B     _handleEntry
218 
219 _hwiActiveCheckNext
220     ADD   R2, R2, #4                        ; next NVIC ACT ADDR
221     SUBS  R12, R12, #1
222     BNE   _hwiActiveCheck
223 
224     ;/*NMI interrupt excption*/
225     LDR   R2, =OS_NVIC_SHCSRS
226     LDRH  R2,[R2]
227     LDR   R3,=OS_NVIC_SHCSR_MASK
228     AND   R2, R2,R3
229     CMP   R2,#0
230     BNE   _ExcInMSP
231     ; exc occurred in Task or Init or exc
232     ; reserved for register info from task stack
233 
234     LDR  R2, =g_taskScheduled
235     LDR  R2, [R2]
236     TST  R2, #1         ; OS_FLG_BGD_ACTIVE
237     BEQ  _ExcInMSP                      ; if exc occurred in Init then branch
238 
239 
240     CMP   LR, #0xFFFFFFED               ;auto push floating registers
241     BNE   _NoFloatInPsp
242 
243     ; exc occurred in Task
244     MOV   R2,  R13
245     SUB   R13, #96                      ; add 8 Bytes reg(for STMFD)
246 
247     MRS   R3,  PSP
248     ADD   R12, R3, #104
249     PUSH  {R12}    ; save task SP
250 
251     MRS   R12, PRIMASK
252     PUSH {R4-R12}
253     VPUSH {D8-D15}
254 
255     ; copy auto saved task register
256 
257     LDMFD R3!, {R4-R11}                  ; R4-R11 store PSP reg(auto push when exc in task)
258     VLDMIA  R3!, {D8-D15}
259     VSTMDB  R2!, {D8-D15}
260     STMFD R2!, {R4-R11}
261     B     _handleEntry
262 
263 _NoFloatInPsp
264     MOV   R2,  R13                           ;no auto push floating registers
265     SUB   R13, #32                      ; add 8 Bytes reg(for STMFD)
266 
267     MRS   R3,  PSP
268     ADD   R12, R3, #32
269     PUSH  {R12}    ; save task SP
270 
271     MRS   R12, PRIMASK
272     PUSH {R4-R12}
273 
274     LDMFD R3, {R4-R11}                  ; R4-R11 store PSP reg(auto push when exc in task)
275     STMFD R2!, {R4-R11}
276     ORR   R0, R0, #FLAG_NO_FLOAT
277 
278 _handleEntry
279     MOV R3, R13                         ; R13:the 4th param
280     CPSID I
281     CPSID F
282     B  HalExcHandleEntry
283 
284     NOP
285     END
286