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