• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2022-11-22
13  * Description: 硬中断。
14  */
15 #include "prt_hwi_external.h"
16 #include "prt_task_external.h"
17 #include "prt_irq_external.h"
18 #include "prt_hwi_internal.h"
19 
20 /*
21  * 描述: GIC模块初始化
22  */
OsHwiGICInit(void)23 INIT_SEC_L4_TEXT void OsHwiGICInit(void)
24 {
25     return;
26 }
27 
28 /*
29  * 描述: 获取硬中断优先级
30  */
OsHwiPriorityGet(HwiHandle hwiNum)31 INIT_SEC_L4_TEXT U32 OsHwiPriorityGet(HwiHandle hwiNum)
32 {
33     return OsGicGetPriority(hwiNum);
34 }
35 
36 /*
37  * 描述: 设置硬中断优先级
38  */
OsHwiPrioritySet(HwiHandle hwiNum,HwiPrior hwiPrio)39 INIT_SEC_L4_TEXT void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio)
40 {
41     OS_ERR_RECORD(OsGicSetPriority(hwiNum, hwiPrio));
42 }
43 
44 /*
45  * 描述: 禁止指定中断
46  */
PRT_HwiDisable(HwiHandle hwiNum)47 OS_SEC_L2_TEXT U32 PRT_HwiDisable(HwiHandle hwiNum)
48 {
49     if (hwiNum > OS_HWI_MAX) {
50         return OS_ERRNO_HWI_NUM_INVALID;
51     }
52     OsGicDisableInt(hwiNum);
53 
54     return OS_OK;
55 }
56 
57 /*
58  * 描述: 使能指定中断
59  */
PRT_HwiEnable(HwiHandle hwiNum)60 OS_SEC_L2_TEXT U32 PRT_HwiEnable(HwiHandle hwiNum)
61 {
62     if (hwiNum > OS_HWI_MAX) {
63         return OS_ERRNO_HWI_NUM_INVALID;
64     }
65     OsGicEnableInt(hwiNum);
66 
67     return OS_OK;
68 }
69 
70 /*
71  * 描述: 触发核间SGI中断,放置OS_SEC_TEXT段
72  */
OsHwiMcTrigger(U32 coreMask,U32 hwiNum)73 OS_SEC_TEXT void OsHwiMcTrigger(U32 coreMask, U32 hwiNum)
74 {
75     OsGicTrigIntToCores(hwiNum, coreMask);
76     return;
77 }
78 
79 /*
80  * 描述: 上报中断号错误
81  */
OsHwiReportHwiNumErr(void)82 OS_SEC_TEXT void OsHwiReportHwiNumErr(void)
83 {
84     OS_REPORT_ERROR(OS_ERRNO_HWI_HW_REPORT_HWINO_INVALID);
85     return;
86 }
87 
88 /*
89  * 描述: 中断处理, 调用处外部已关中断
90  */
OsHwiDispatchHandle(U32 arg1)91 OS_SEC_L0_TEXT void OsHwiDispatchHandle(U32 arg1)
92 {
93     U32 hwiNum;
94     (void)arg1;
95 
96     UNI_FLAG |= OS_FLG_HWI_ACTIVE;
97     OS_INT_COUNT++;
98     /* ARMv8硬件约束,fiq和和irq都会在在异常和入口被mask掉 */
99     /* 此处需要同时清F比特,确保FIQ能及时响应 */
100     OsFiqEnable();
101 
102     hwiNum = OsHwiNumGet();
103 
104     if (OS_HWI_CLEAR_CHECK(hwiNum) || OS_HWI_NUM_CHECK(hwiNum)) {
105         goto OS_HWI_CONTINUE;
106     }
107 
108     OsHwiNestedIntEnable();
109     OsHwiHookDispatcher(hwiNum);
110     OsHwiNestedIntDisable();
111 
112 OS_HWI_CONTINUE:
113     // 清除中断位
114     OsHwiClear(hwiNum);
115     OS_INT_COUNT--;
116     /* 不支持中断嵌套,但这里防止中断服务程序中错误打开了中断 */
117     if (OS_INT_COUNT > 0) {
118         return;
119     }
120 
121     UNI_FLAG &= ~OS_FLG_HWI_ACTIVE;
122 
123     OsHwiDispatchTail();
124 }
125 
126 /*
127  * 描述: 中断处理入口, 调用处外部已关中断
128  */
OsHwiDispatch(uintptr_t sp,U32 arg1)129 OS_SEC_L0_TEXT void OsHwiDispatch(uintptr_t sp, U32 arg1)
130 {
131     // 该函数体内有切栈动作, 不允许有局部变量
132     if (!OS_INT_ACTIVE) {
133         // 被打断的是任务
134         RUNNING_TASK->stackPointer = (void *)sp;
135         OsSetSysStackSP(OsGetSysStackSP(), arg1);
136     }
137 
138     // 有可能切栈, 中断入口函数不使用局部变量
139     OsHwiDispatchHandle(arg1);
140 }
141 
142 /*
143  * 描述: 开启全局可屏蔽中断。
144  */
PRT_HwiUnLock(void)145 OS_SEC_L0_TEXT uintptr_t PRT_HwiUnLock(void)
146 {
147     uintptr_t state = 0;
148 
149     OS_EMBED_ASM(
150         "mrs %0, DAIF      \n"
151         "msr DAIFClr, %1   \n"
152         : "=r"(state)
153         : "i"(DAIF_IRQ_BIT)
154         : "memory", "cc");
155 
156     return state & INT_MASK;
157 }
158 
159 /*
160  * 描述: 关闭全局可屏蔽中断。
161  */
PRT_HwiLock(void)162 OS_SEC_L0_TEXT uintptr_t PRT_HwiLock(void)
163 {
164     uintptr_t state = 0;
165     OS_EMBED_ASM(
166         "mrs %0, DAIF      \n"
167         "msr DAIFSet, %1   \n"
168         : "=r"(state)
169         : "i"(DAIF_IRQ_BIT)
170         : "memory", "cc");
171     return state & INT_MASK;
172 }
173 
174 /*
175  * 描述: 恢复原中断状态寄存器。
176  */
PRT_HwiRestore(uintptr_t intSave)177 OS_SEC_L0_TEXT void PRT_HwiRestore(uintptr_t intSave)
178 {
179     if ((intSave & INT_MASK) == 0) {
180         OS_EMBED_ASM(
181             "msr DAIFClr, %0\n"
182             :
183             : "i"(DAIF_IRQ_BIT)
184             : "memory", "cc");
185     } else {
186         OS_EMBED_ASM(
187             "msr DAIFSet, %0\n"
188             :
189             : "i"(DAIF_IRQ_BIT)
190             : "memory", "cc");
191     }
192     return;
193 }