• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 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 #include <stdarg.h>
33 #include "securec.h"
34 #include "los_context.h"
35 #include "los_arch_context.h"
36 #include "los_arch_interrupt.h"
37 #include "los_debug.h"
38 #include "los_hook.h"
39 #include "los_task.h"
40 #include "los_sched.h"
41 #include "los_memory.h"
42 #include "los_membox.h"
43 
44 #define INT_OFFSET       6
45 #define PRI_OFF_PER_INT  8
46 #define PRI_PER_REG      4
47 #define PRI_OFF_IN_REG   6
48 #define PRI_BITS         2
49 #define PRI_HI           0
50 #define PRI_LOW          7
51 #define MASK_8_BITS      0xFF
52 #define MASK_32_BITS     0xFFFFFFFF
53 #define BYTES_OF_128_INT 4
54 
55 CHAR g_trapStackBase[OS_TRAP_STACK_SIZE];
56 
57 VIC_TYPE *VIC_REG = (VIC_TYPE *)VIC_REG_BASE;
58 
HalGetPsr(VOID)59 UINT32 HalGetPsr(VOID)
60 {
61     UINT32 intSave;
62     __asm__ volatile("mfcr %0, psr" : "=r" (intSave) : : "memory");
63     return intSave;
64 }
65 
HalSetVbr(UINT32 intSave)66 UINT32 HalSetVbr(UINT32 intSave)
67 {
68     __asm__ volatile("mtcr %0, vbr" : : "r"(intSave)  : "memory");
69     return intSave;
70 }
71 
ArchIntLock(VOID)72 UINT32 ArchIntLock(VOID)
73 {
74     UINT32 intSave;
75     __asm__ __volatile__(
76         "mfcr    %0, psr \n"
77         "psrclr ie"
78         : "=r"(intSave)
79         :
80         : "memory");
81     return intSave;
82 }
83 
ArchIntUnLock(VOID)84 UINT32 ArchIntUnLock(VOID)
85 {
86     UINT32 intSave;
87     __asm__ __volatile__(
88         "mfcr   %0, psr \n"
89         "psrset ie"
90         : "=r"(intSave)
91         :
92         : "memory");
93     return intSave;
94 }
95 
ArchIntRestore(UINT32 intSave)96 VOID ArchIntRestore(UINT32 intSave)
97 {
98     __asm__ __volatile__("mtcr %0, psr" : : "r"(intSave));
99 }
100 
ArchIntLocked(VOID)101 UINT32 ArchIntLocked(VOID)
102 {
103     UINT32 intSave;
104     __asm__ volatile("mfcr %0, psr" : "=r" (intSave) : : "memory");
105     return !(intSave & (1 << INT_OFFSET));
106 }
107 
HwiUnmask(HWI_HANDLE_T hwiNum)108 STATIC UINT32 HwiUnmask(HWI_HANDLE_T hwiNum)
109 {
110     UINT32 intSave;
111 
112     intSave = LOS_IntLock();
113     VIC_REG->ISER[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT));
114     VIC_REG->ISSR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT));
115     LOS_IntRestore(intSave);
116 
117     return LOS_OK;
118 }
119 
HwiSetPriority(HWI_HANDLE_T hwiNum,UINT8 priority)120 STATIC UINT32 HwiSetPriority(HWI_HANDLE_T hwiNum, UINT8 priority)
121 {
122     UINT32 intSave;
123 
124     intSave = LOS_IntLock();
125     VIC_REG->IPR[hwiNum / PRI_PER_REG] |= (((priority << PRI_OFF_IN_REG) << (hwiNum % PRI_PER_REG)) * PRI_OFF_PER_INT);
126     LOS_IntRestore(intSave);
127 
128     return LOS_OK;
129 }
130 
HwiMask(HWI_HANDLE_T hwiNum)131 STATIC UINT32 HwiMask(HWI_HANDLE_T hwiNum)
132 {
133     UINT32 intSave;
134 
135     intSave = LOS_IntLock();
136     VIC_REG->ICER[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT));
137     LOS_IntRestore(intSave);
138 
139     return LOS_OK;
140 }
141 
HwiPending(HWI_HANDLE_T hwiNum)142 STATIC UINT32 HwiPending(HWI_HANDLE_T hwiNum)
143 {
144     UINT32 intSave;
145 
146     intSave = LOS_IntLock();
147     VIC_REG->ISPR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT));
148     LOS_IntRestore(intSave);
149 
150     return LOS_OK;
151 }
152 
HwiClear(HWI_HANDLE_T hwiNum)153 STATIC UINT32 HwiClear(HWI_HANDLE_T hwiNum)
154 {
155     VIC_REG->ICPR[hwiNum / OS_SYS_VECTOR_CNT] = (UINT32)(1UL << (hwiNum % OS_SYS_VECTOR_CNT));
156 
157     return LOS_OK;
158 }
159 
160 /* ****************************************************************************
161  Function    : HwiNumGet
162  Description : Get an interrupt number
163  Input       : None
164  Output      : None
165  Return      : Interrupt Indexes number
166  **************************************************************************** */
HwiNumGet(VOID)167 STATIC UINT32 HwiNumGet(VOID)
168 {
169     return (HalGetPsr() >> PSR_VEC_OFFSET) & MASK_8_BITS;
170 }
171 
HwiCreate(HWI_HANDLE_T hwiNum,HWI_PRIOR_T hwiPrio)172 STATIC UINT32 HwiCreate(HWI_HANDLE_T hwiNum, HWI_PRIOR_T hwiPrio)
173 {
174     HwiSetPriority(hwiNum, (UINT8)hwiPrio);
175     HwiUnmask(hwiNum);
176     return LOS_OK;
177 }
178 
179 STATIC HwiControllerOps g_archHwiOps = {
180     .enableIrq      = HwiUnmask,
181     .disableIrq     = HwiMask,
182     .setIrqPriority = HwiSetPriority,
183     .getCurIrqNum   = HwiNumGet,
184     .triggerIrq     = HwiPending,
185     .clearIrq       = HwiClear,
186     .createIrq      = HwiCreate,
187 };
188 
ArchIntOpsGet(VOID)189 HwiControllerOps *ArchIntOpsGet(VOID)
190 {
191     return &g_archHwiOps;
192 }
193 
194 /* ****************************************************************************
195  Function    : HalInterrupt
196  Description : Hardware interrupt entry function
197  Input       : None
198  Output      : None
199  Return      : None
200  **************************************************************************** */
HalInterrupt(VOID)201 LITE_OS_SEC_TEXT VOID HalInterrupt(VOID)
202 {
203     UINT32 hwiIndex;
204     UINT32 intSave;
205 
206     intSave = LOS_IntLock();
207     g_intCount++;
208     LOS_IntRestore(intSave);
209 
210     hwiIndex = HwiNumGet();
211     OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiIndex);
212 
213     HalPreInterruptHandler(hwiIndex);
214 #if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
215     if (g_hwiHandlerForm[hwiIndex].pfnHandler != 0) {
216         g_hwiHandlerForm[hwiIndex].pfnHandler((VOID *)g_hwiHandlerForm[hwiIndex].pParm);
217     }
218 #else
219     if (g_hwiHandlerForm[hwiIndex] != 0) {
220         g_hwiHandlerForm[hwiIndex]();
221     }
222 #endif
223 
224     HalAftInterruptHandler(hwiIndex);
225 
226     OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiIndex);
227 
228     intSave = LOS_IntLock();
229     g_intCount--;
230 #ifndef CPU_CK804
231     HalIrqEndCheckNeedSched();
232 #endif
233     LOS_IntRestore(intSave);
234 }
235 
236 ExcInfo g_excInfo = {0};
237 
238 #if (LOSCFG_KERNEL_PRINTF != 0)
OsExcTypeInfo(const ExcInfo * excInfo)239 STATIC VOID OsExcTypeInfo(const ExcInfo *excInfo)
240 {
241     CHAR *phaseStr[] = {"exc in init", "exc in task", "exc in hwi"};
242 
243     PRINTK("Type      = %d\n", excInfo->type);
244     PRINTK("ThrdPid   = %d\n", excInfo->thrdPid);
245     PRINTK("Phase     = %s\n", phaseStr[excInfo->phase]);
246     PRINTK("FaultAddr = 0x%x\n", excInfo->faultAddr);
247 }
248 
OsExcCurTaskInfo(const ExcInfo * excInfo)249 STATIC VOID OsExcCurTaskInfo(const ExcInfo *excInfo)
250 {
251     PRINTK("Current task info:\n");
252     if (excInfo->phase == OS_EXC_IN_TASK) {
253         LosTaskCB *taskCB = OS_TCB_FROM_TID(LOS_CurTaskIDGet());
254         PRINTK("Task name = %s\n", taskCB->taskName);
255         PRINTK("Task ID   = %d\n", taskCB->taskID);
256         PRINTK("Task SP   = 0x%x\n", (UINTPTR)taskCB->stackPointer);
257         PRINTK("Task ST   = 0x%x\n", taskCB->topOfStack);
258         PRINTK("Task SS   = 0x%x\n", taskCB->stackSize);
259     } else if (excInfo->phase == OS_EXC_IN_HWI) {
260         PRINTK("Exception occur in interrupt phase!\n");
261     } else {
262         PRINTK("Exception occur in system init phase!\n");
263     }
264 }
265 
OsExcRegInfo(const ExcInfo * excInfo)266 STATIC VOID OsExcRegInfo(const ExcInfo *excInfo)
267 {
268     EXC_CONTEXT_S *excContext = excInfo->context;
269     PRINTK("Exception reg dump:\n");
270     PRINTK("R0         = 0x%x\n"
271            "R1         = 0x%x\n"
272            "R2         = 0x%x\n"
273            "R3         = 0x%x\n"
274            "R4         = 0x%x\n"
275            "R5         = 0x%x\n"
276            "R6         = 0x%x\n"
277            "R7         = 0x%x\n"
278            "R8         = 0x%x\n"
279            "R9         = 0x%x\n"
280            "R10        = 0x%x\n"
281            "R11        = 0x%x\n"
282            "R12        = 0x%x\n"
283            "R13        = 0x%x\n"
284            "R14        = 0x%x\n"
285            "R15        = 0x%x\n"
286            "EPSR       = 0x%x\n"
287            "EPC        = 0x%x\n",
288            excContext->R0, excContext->R1, excContext->R2, excContext->R3, excContext->R4, excContext->R5,
289            excContext->R6, excContext->R7, excContext->R8, excContext->R9, excContext->R10, excContext->R11,
290            excContext->R12, excContext->R13, excContext->R14, excContext->R15, excContext->EPSR,
291            excContext->EPC);
292 }
293 
294 #if (LOSCFG_KERNEL_BACKTRACE == 1)
OsExcBackTraceInfo(const ExcInfo * excInfo)295 STATIC VOID OsExcBackTraceInfo(const ExcInfo *excInfo)
296 {
297     UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = {0};
298     UINT32 index;
299 
300     OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, excInfo->context->R14);
301 
302     PRINTK("----- backtrace start -----\n");
303     for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
304         if (LR[index] == 0) {
305             break;
306         }
307         PRINTK("backtrace %d -- lr = 0x%x\n", index, LR[index]);
308     }
309     PRINTK("----- backtrace end -----\n");
310 }
311 #endif
312 
OsExcMemPoolCheckInfo(VOID)313 STATIC VOID OsExcMemPoolCheckInfo(VOID)
314 {
315     PRINTK("\r\nmemory pools check:\n");
316 #if (LOSCFG_PLATFORM_EXC == 1)
317     MemInfoCB memExcInfo[OS_SYS_MEM_NUM];
318     UINT32 errCnt;
319     UINT32 i;
320 
321     (VOID)memset_s(memExcInfo, sizeof(memExcInfo), 0, sizeof(memExcInfo));
322 
323     errCnt = OsMemExcInfoGet(OS_SYS_MEM_NUM, memExcInfo);
324     if (errCnt < OS_SYS_MEM_NUM) {
325         errCnt += OsMemboxExcInfoGet(OS_SYS_MEM_NUM - errCnt, memExcInfo + errCnt);
326     }
327 
328     if (errCnt == 0) {
329         PRINTK("all memory pool check passed!\n");
330         return;
331     }
332 
333     for (i = 0; i < errCnt; i++) {
334         PRINTK("pool num    = %d\n", i);
335         PRINTK("pool type   = %d\n", memExcInfo[i].type);
336         PRINTK("pool addr   = 0x%x\n", memExcInfo[i].startAddr);
337         PRINTK("pool size   = 0x%x\n", memExcInfo[i].size);
338         PRINTK("pool free   = 0x%x\n", memExcInfo[i].free);
339         PRINTK("pool blkNum = %d\n", memExcInfo[i].blockSize);
340         PRINTK("pool error node addr  = 0x%x\n", memExcInfo[i].errorAddr);
341         PRINTK("pool error node len   = 0x%x\n", memExcInfo[i].errorLen);
342         PRINTK("pool error node owner = %d\n", memExcInfo[i].errorOwner);
343     }
344 #endif
345     UINT32 ret = LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR);
346     if (ret == LOS_OK) {
347         PRINTK("system heap memcheck over, all passed!\n");
348     }
349 
350     PRINTK("memory pool check end!\n");
351 }
352 #endif
353 
OsExcInfoDisplay(const ExcInfo * excInfo)354 STATIC VOID OsExcInfoDisplay(const ExcInfo *excInfo)
355 {
356 #if (LOSCFG_KERNEL_PRINTF != 0)
357     PRINTK("*************Exception Information**************\n");
358     OsExcTypeInfo(excInfo);
359     OsExcCurTaskInfo(excInfo);
360     OsExcRegInfo(excInfo);
361 #if (LOSCFG_KERNEL_BACKTRACE == 1)
362     OsExcBackTraceInfo(excInfo);
363 #endif
364     OsGetAllTskInfo();
365     OsExcMemPoolCheckInfo();
366 #endif
367 }
368 
HalExcHandleEntry(EXC_CONTEXT_S * excBufAddr,UINT32 faultAddr)369 LITE_OS_SEC_TEXT_INIT VOID HalExcHandleEntry(EXC_CONTEXT_S *excBufAddr, UINT32 faultAddr)
370 {
371     UINT16 tmpFlag = ((excBufAddr->EPSR >> PSR_VEC_OFFSET) & MASK_8_BITS);
372     g_excInfo.nestCnt++;
373     UINT32 excType = (HalGetPsr() >> PSR_VEC_OFFSET) & MASK_8_BITS;
374     g_excInfo.type = excType;
375 
376     g_excInfo.faultAddr = faultAddr;
377 
378     if (g_losTask.runTask != NULL) {
379         if (tmpFlag > 0) {
380             g_excInfo.phase = OS_EXC_IN_HWI;
381             g_excInfo.thrdPid = tmpFlag;
382         } else {
383             g_excInfo.phase = OS_EXC_IN_TASK;
384             g_excInfo.thrdPid = g_losTask.runTask->taskID;
385         }
386     } else {
387         g_excInfo.phase = OS_EXC_IN_INIT;
388         g_excInfo.thrdPid = OS_NULL_INT;
389     }
390     g_excInfo.context = excBufAddr;
391 
392     OsDoExcHook(EXC_INTERRUPT);
393     OsExcInfoDisplay(&g_excInfo);
394     ArchSysExit();
395 }
396 
397 /* stack protector */
398 WEAK UINT32 __stack_chk_guard = 0xd00a0dff;
399 
__stack_chk_fail(VOID)400 WEAK VOID __stack_chk_fail(VOID)
401 {
402     /* __builtin_return_address is a builtin function, building in gcc */
403     LOS_Panic("stack-protector: Kernel stack is corrupted in: %x\n",
404               __builtin_return_address(0));
405 }
406 
HalHwiHandleReInit(UINT32 hwiFormAddr)407 WEAK void HalHwiHandleReInit(UINT32 hwiFormAddr)
408 {
409 }
410 
411 /* ****************************************************************************
412  Function    : HalHwiInit
413  Description : initialization of the hardware interrupt
414  Input       : None
415  Output      : None
416  Return      : None
417  **************************************************************************** */
HalHwiInit(VOID)418 LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID)
419 {
420     UINT32 i;
421 
422     HWI_PROC_FUNC *hwiForm = (HWI_PROC_FUNC *)ArchGetHwiFrom();
423     for (i = 1; i < OS_SYS_VECTOR_CNT; i++) {
424         hwiForm[i] = (HWI_PROC_FUNC)HandleEntry;
425     }
426 
427     for (i = OS_SYS_VECTOR_CNT; i < (LOSCFG_PLATFORM_HWI_LIMIT + OS_SYS_VECTOR_CNT); i++) {
428         hwiForm[i] = (HWI_PROC_FUNC)IrqEntry;
429     }
430     HalHwiHandleReInit((UINT32)hwiForm);
431 
432     HalSetVbr((UINT32)hwiForm);
433     for (i = 0; i < BYTES_OF_128_INT; i++) {
434         VIC_REG->IABR[i] = 0x0;
435         VIC_REG->ICPR[i] = MASK_32_BITS;
436     }
437     return;
438 }
439 
440