• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2020, 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 #include <stdio.h>
33 #include <stdarg.h>
34 #include "los_arch.h"
35 #include "los_arch_interrupt.h"
36 #include "los_arch_context.h"
37 #include "los_task.h"
38 #include "los_sched.h"
39 #include "los_debug.h"
40 #include "los_hook.h"
41 #include "riscv_hal.h"
42 
43 
44 LosExcInfo g_excInfo;
45 #define RISCV_EXC_TYPE_NUM 16
46 #define RISCV_EXC_LOAD_MISALIGNED 4
47 #define RISCV_EXC_STORE_MISALIGNED 6
48 const CHAR g_excInformation[RISCV_EXC_TYPE_NUM][50] = {
49     { "Instruction address misaligned!" },
50     { "Instruction access fault!" },
51     { "Illegal instruction" },
52     { "Breakpoint!" },
53     { "Load address misaligned!" },
54     { "Load access fault!" },
55     { "Store/AMO address misaligned!" },
56     { "Store/AMO access fault!" },
57     { "Environment call form U-mode!" },
58     { "Environment call form S-mode!" },
59     { "Reserved!" },
60     { "Environment call form M-mode!" },
61     { "Instruction page fault!" },
62     { "Load page fault!" },
63     { "Reserved!" },
64     { "Store/AMO page fault!" },
65 };
66 
67 LITE_OS_SEC_BSS UINT32  g_intCount = 0;
68 LITE_OS_SEC_BSS UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM];
69 LITE_OS_SEC_DATA_INIT HWI_HANDLE_FORM_S g_hwiForm[OS_HWI_MAX_NUM] = {
70     { .pfnHook = NULL, .uwParam = 0 }, // 0 User software interrupt handler
71     { .pfnHook = NULL, .uwParam = 0 }, // 1 Supervisor software interrupt handler
72     { .pfnHook = NULL, .uwParam = 0 }, // 2 Reserved
73     { .pfnHook = HalHwiDefaultHandler, .uwParam = 0 }, // 3 Machine software interrupt handler
74     { .pfnHook = NULL, .uwParam = 0 }, // 4 User timer interrupt handler
75     { .pfnHook = NULL, .uwParam = 0 }, // 5 Supervisor timer interrupt handler
76     { .pfnHook = NULL, .uwParam = 0 }, // 6  Reserved
77     { .pfnHook = HalHwiDefaultHandler, .uwParam = 0 }, // 7 Machine timer interrupt handler
78     { .pfnHook = NULL, .uwParam = 0 }, // 8  User external interrupt handler
79     { .pfnHook = NULL, .uwParam = 0 }, // 9 Supervisor external interrupt handler
80     { .pfnHook = NULL, .uwParam = 0 }, // 10 Reserved
81     { .pfnHook = HalHwiDefaultHandler, .uwParam = 0 }, // 11 Machine external interrupt handler
82     { .pfnHook = HalHwiDefaultHandler, .uwParam = 0 }, // 12 NMI handler
83     { .pfnHook = NULL, .uwParam = 0 }, // 13 Reserved
84     { .pfnHook = NULL, .uwParam = 0 }, // 14 Reserved
85     { .pfnHook = NULL, .uwParam = 0 }, // 15 Reserved
86     { .pfnHook = NULL, .uwParam = 0 }, // 16 Reserved
87     { .pfnHook = NULL, .uwParam = 0 }, // 17 Reserved
88     { .pfnHook = NULL, .uwParam = 0 }, // 18 Reserved
89     { .pfnHook = NULL, .uwParam = 0 }, // 19 Reserved
90     { .pfnHook = NULL, .uwParam = 0 }, // 20 Reserved
91     { .pfnHook = NULL, .uwParam = 0 }, // 21 Reserved
92     { .pfnHook = NULL, .uwParam = 0 }, // 22 Reserved
93     { .pfnHook = NULL, .uwParam = 0 }, // 23 Reserved
94     { .pfnHook = NULL, .uwParam = 0 }, // 24 Reserved
95     { .pfnHook = NULL, .uwParam = 0 }, // 25 Reserved
96 };
97 
HalHwiDefaultHandler(VOID * arg)98 LITE_OS_SEC_TEXT_INIT VOID HalHwiDefaultHandler(VOID *arg)
99 {
100     (VOID)arg;
101     PRINT_ERR("default handler\n");
102     while (1) {
103     }
104 }
105 
HalHwiInit(VOID)106 LITE_OS_SEC_TEXT_INIT VOID HalHwiInit(VOID)
107 {
108     UINT32 index;
109     for (index = OS_RISCV_SYS_VECTOR_CNT; index < OS_HWI_MAX_NUM; index++) {
110         g_hwiForm[index].pfnHook = HalHwiDefaultHandler;
111         g_hwiForm[index].uwParam = 0;
112     }
113 }
114 
115 typedef VOID (*HwiProcFunc)(VOID *arg);
HalHwiInterruptDone(HWI_HANDLE_T hwiNum)116 __attribute__((section(".interrupt.text"))) VOID HalHwiInterruptDone(HWI_HANDLE_T hwiNum)
117 {
118     g_intCount++;
119 
120     OsHookCall(LOS_HOOK_TYPE_ISR_ENTER, hwiNum);
121 
122     HWI_HANDLE_FORM_S *hwiForm = &g_hwiForm[hwiNum];
123     HwiProcFunc func = (HwiProcFunc)(hwiForm->pfnHook);
124     func(hwiForm->uwParam);
125 
126     ++g_hwiFormCnt[hwiNum];
127 
128     OsHookCall(LOS_HOOK_TYPE_ISR_EXIT, hwiNum);
129 
130     g_intCount--;
131 }
132 
HalGetHwiFormCnt(HWI_HANDLE_T hwiNum)133 LITE_OS_SEC_TEXT UINT32 HalGetHwiFormCnt(HWI_HANDLE_T hwiNum)
134 {
135     if (hwiNum < OS_HWI_MAX_NUM) {
136         return g_hwiFormCnt[hwiNum];
137     }
138 
139     return LOS_NOK;
140 }
141 
HalGetHwiForm(VOID)142 LITE_OS_SEC_TEXT HWI_HANDLE_FORM_S *HalGetHwiForm(VOID)
143 {
144     return g_hwiForm;
145 }
146 
147 
ArchIsIntActive(VOID)148 inline UINT32 ArchIsIntActive(VOID)
149 {
150     return (g_intCount > 0);
151 }
152 
153 /*****************************************************************************
154  Function    : ArchHwiCreate
155  Description : create hardware interrupt
156  Input       : hwiNum     --- hwi num to create
157                hwiPrio    --- priority of the hwi
158                hwiMode    --- hwi interrupt mode
159                hwiHandler --- hwi handler
160                irqParam   --- param of the hwi handler
161  Output      : None
162  Return      : LOS_OK on success or error code on failure
163  *****************************************************************************/
ArchHwiCreate(HWI_HANDLE_T hwiNum,HWI_PRIOR_T hwiPrio,HWI_MODE_T hwiMode,HWI_PROC_FUNC hwiHandler,HwiIrqParam * irqParam)164 LITE_OS_SEC_TEXT UINT32 ArchHwiCreate(HWI_HANDLE_T hwiNum,
165                                       HWI_PRIOR_T hwiPrio,
166                                       HWI_MODE_T hwiMode,
167                                       HWI_PROC_FUNC hwiHandler,
168                                       HwiIrqParam *irqParam)
169 {
170     UINT32 intSave;
171 
172     if (hwiHandler == NULL) {
173         return OS_ERRNO_HWI_PROC_FUNC_NULL;
174     }
175     if (hwiNum >= OS_HWI_MAX_NUM) {
176         return OS_ERRNO_HWI_NUM_INVALID;
177     }
178     if (g_hwiForm[hwiNum].pfnHook == NULL) {
179         return OS_ERRNO_HWI_NUM_INVALID;
180     } else if (g_hwiForm[hwiNum].pfnHook != HalHwiDefaultHandler) {
181         return OS_ERRNO_HWI_NUM_INVALID;
182     }
183     if ((hwiPrio < OS_HWI_PRIO_LOWEST) || (hwiPrio > OS_HWI_PRIO_HIGHEST)) {
184         return OS_ERRNO_HWI_PRIO_INVALID;
185     }
186 
187     intSave = LOS_IntLock();
188     g_hwiForm[hwiNum].pfnHook = hwiHandler;
189     if (irqParam != NULL) {
190         g_hwiForm[hwiNum].uwParam = (VOID *)irqParam->pDevId;
191     } else {
192         g_hwiForm[hwiNum].uwParam = NULL;
193     }
194     if (hwiNum >= OS_RISCV_SYS_VECTOR_CNT) {
195         HalSetLocalInterPri(hwiNum, hwiPrio);
196     }
197 
198     LOS_IntRestore(intSave);
199 
200     return LOS_OK;
201 }
202 
203 /*****************************************************************************
204  Function    : ArchHwiDelete
205  Description : Delete hardware interrupt
206  Input       : hwiNum   --- hwi num to delete
207                irqParam --- param of the hwi handler
208  Return      : LOS_OK on success or error code on failure
209  *****************************************************************************/
ArchHwiDelete(HWI_HANDLE_T hwiNum,HwiIrqParam * irqParam)210 LITE_OS_SEC_TEXT UINT32 ArchHwiDelete(HWI_HANDLE_T hwiNum, HwiIrqParam *irqParam)
211 {
212     (VOID)irqParam;
213     UINT32 intSave;
214 
215     if (hwiNum >= OS_HWI_MAX_NUM) {
216         return OS_ERRNO_HWI_NUM_INVALID;
217     }
218 
219     intSave = LOS_IntLock();
220     g_hwiForm[hwiNum].pfnHook = HalHwiDefaultHandler;
221     g_hwiForm[hwiNum].uwParam = 0;
222     LOS_IntRestore(intSave);
223     return LOS_OK;
224 }
225 
ExcBackTrace(UINTPTR fp)226 STATIC VOID ExcBackTrace(UINTPTR fp)
227 {
228     UINTPTR LR[LOSCFG_BACKTRACE_DEPTH] = { 0 };
229     UINT32 index;
230 
231     OsBackTraceHookCall(LR, LOSCFG_BACKTRACE_DEPTH, 0, fp);
232 
233     PRINTK("----- traceback start -----\n");
234     for (index = 0; index < LOSCFG_BACKTRACE_DEPTH; index++) {
235         if (LR[index] == 0) {
236             break;
237         }
238         PRINTK("traceback %d -- lr = 0x%x\n", index, LR[index]);
239     }
240     PRINTK("----- traceback end -----\n");
241 }
242 
ExcInfoDisplayContext(const LosExcInfo * exc)243 STATIC VOID ExcInfoDisplayContext(const LosExcInfo *exc)
244 {
245     const TaskContext *taskContext = &(exc->context->taskContext);
246 
247     PRINTK("mepc       = 0x%x\n", taskContext->mepc);
248     PRINTK("mstatus    = 0x%x\n", taskContext->mstatus);
249     PRINTK("mtval      = 0x%x\n", exc->context->mtval);
250     PRINTK("mcause     = 0x%x\n", exc->context->mcause);
251     PRINTK("ra         = 0x%x\n", taskContext->ra);
252     PRINTK("sp         = 0x%x\n", taskContext->sp);
253     PRINTK("gp         = 0x%x\n", exc->context->gp);
254     PRINTK("tp         = 0x%x\n", taskContext->tp);
255     PRINTK("t0         = 0x%x\n", taskContext->t0);
256     PRINTK("t1         = 0x%x\n", taskContext->t1);
257     PRINTK("t2         = 0x%x\n", taskContext->t2);
258     PRINTK("s0         = 0x%x\n", taskContext->s0);
259     PRINTK("s1         = 0x%x\n", taskContext->s1);
260     PRINTK("a0         = 0x%x\n", taskContext->a0);
261     PRINTK("a1         = 0x%x\n", taskContext->a1);
262     PRINTK("a2         = 0x%x\n", taskContext->a2);
263     PRINTK("a3         = 0x%x\n", taskContext->a3);
264     PRINTK("a4         = 0x%x\n", taskContext->a4);
265     PRINTK("a5         = 0x%x\n", taskContext->a5);
266     PRINTK("a6         = 0x%x\n", taskContext->a6);
267     PRINTK("a7         = 0x%x\n", taskContext->a7);
268     PRINTK("s2         = 0x%x\n", taskContext->s2);
269     PRINTK("s3         = 0x%x\n", taskContext->s3);
270     PRINTK("s4         = 0x%x\n", taskContext->s4);
271     PRINTK("s5         = 0x%x\n", taskContext->s5);
272     PRINTK("s6         = 0x%x\n", taskContext->s6);
273     PRINTK("s7         = 0x%x\n", taskContext->s7);
274     PRINTK("s8         = 0x%x\n", taskContext->s8);
275     PRINTK("s9         = 0x%x\n", taskContext->s9);
276     PRINTK("s10        = 0x%x\n", taskContext->s10);
277     PRINTK("s11        = 0x%x\n", taskContext->s11);
278     PRINTK("t3         = 0x%x\n", taskContext->t3);
279     PRINTK("t4         = 0x%x\n", taskContext->t4);
280     PRINTK("t5         = 0x%x\n", taskContext->t5);
281     PRINTK("t6         = 0x%x\n", taskContext->t6);
282 
283     ExcBackTrace(taskContext->s0);
284 }
285 
ExcInfoDisplay(const LosExcContext * excBufAddr)286 STATIC VOID ExcInfoDisplay(const LosExcContext *excBufAddr)
287 {
288     PRINTK("\nException Information     \n");
289 
290     if (g_excInfo.type < RISCV_EXC_TYPE_NUM) {
291         PRINTK("Exc  type : Oops  - %s\n", g_excInformation[g_excInfo.type]);
292     } else {
293         PRINTK("Exc  type : Oops  - Invalid\n");
294     }
295 
296     if (LOS_TaskIsRunning()) {
297         PRINTK("taskName = %s\n", g_losTask.runTask->taskName);
298         PRINTK("taskID = %u\n", g_losTask.runTask->taskID);
299     } else {
300         PRINTK("The exception occurs during system startup!\n");
301     }
302     PRINTK("system mem addr:0x%x\n", (UINTPTR)LOSCFG_SYS_HEAP_ADDR);
303     ExcInfoDisplayContext(&g_excInfo);
304 }
305 
HalUnalignedAccessFix(UINTPTR mcause,UINTPTR mepc,UINTPTR mtval,VOID * sp)306 WEAK UINT32 HalUnalignedAccessFix(UINTPTR mcause, UINTPTR mepc, UINTPTR mtval, VOID *sp)
307 {
308     /* Unaligned access fixes are not supported by default */
309     PRINTK("Unaligned access fixes are not supported by default!\n");
310     return LOS_NOK;
311 }
312 
HalExcEntry(const LosExcContext * excBufAddr)313 VOID HalExcEntry(const LosExcContext *excBufAddr)
314 {
315     UINT32 ret;
316     g_excInfo.type = excBufAddr->mcause & 0x1FF;
317     g_excInfo.context = (LosExcContext *)excBufAddr;
318     if (g_excInfo.nestCnt > 2) { /* 2: Number of layers of exception nesting */
319         PRINTK("hard fault!\n");
320         goto SYSTEM_DEATH;
321     }
322 
323     if ((g_excInfo.type == RISCV_EXC_LOAD_MISALIGNED) ||
324         (g_excInfo.type == RISCV_EXC_STORE_MISALIGNED)) {
325         ret = HalUnalignedAccessFix(excBufAddr->mcause, excBufAddr->taskContext.mepc, excBufAddr->mtval,
326                                     (VOID *)excBufAddr);
327         if (!ret) {
328             return;
329         }
330     }
331 
332     ExcInfoDisplay(excBufAddr);
333 
334     if (LOS_TaskIsRunning()) {
335         PRINTK("----------------All Task information ------------\n");
336         OsGetAllTskInfo();
337     }
338 
339 SYSTEM_DEATH:
340     OsDoExcHook(EXC_INTERRUPT);
341     while (1) {
342     }
343 }
344 
345