• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-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: 2009-12-22
13  * Description: Hardware interrupt implementation
14  */
15 #include "prt_hook_external.h"
16 #include "prt_lib_external.h"
17 #include "prt_task_external.h"
18 #include "prt_hwi_internal.h"
19 
20 #if defined(OS_OPTION_HWI_MAX_NUM_CONFIG)
21 OS_SEC_BSS U32 g_hwiMaxNumConfig;
22 #endif
23 OS_SEC_BSS OsVoidFunc g_excTrap;
24 /*
25  * 重定位以后的向量表,
26  * 其最后一个四字节表示当前运行的中断号,初始化系统定义异常向量,以便初始化阶段异常接管
27  */
28 VEC_SEC_DATA HwiPubintFunc g_hwiTable[OS_MX_VECTOR_CNT + 1] = {
29     (HwiPubintFunc)MSTACK_VECTOR,
30     (HwiPubintFunc)OsResetVector,
31 };
32 
OsScheduleInit(void)33 OS_SEC_L4_TEXT void OsScheduleInit(void)
34 {
35     OS_SET_VECTOR(OS_EXC_PEND_SV, OsPendSv);
36     OS_SET_VECTOR(OS_EXC_SVC_CALL, OsSvchandler);
37 
38     NVIC_SET_EXC_PRI(OS_EXC_PEND_SV, OS_HWI_PRI_LOWEST);
39     NVIC_SET_EXC_PRI(OS_EXC_SVC_CALL, OS_HWI_PRI_HIGHEST);
40 }
41 
OsHwiGICInit(void)42 OS_SEC_L4_TEXT void OsHwiGICInit(void)
43 {
44     U32 loop;
45     /* 系统中断向量表初始化 */
46     for (loop = 0; loop < OS_MX_SYS_VECTOR_CNT; loop++) {
47         g_hwiTable[loop] = (HwiPubintFunc)OsHwiDefaultHandler;
48     }
49     OS_SET_VECTOR(0, (HwiPubintFunc)MSTACK_VECTOR);
50     OS_SET_VECTOR(OS_EXC_RESET, OsResetVector);
51     OS_SET_VECTOR(OS_EXC_NMI, OsExcNmi);
52     OS_SET_VECTOR(OS_EXC_HARD_FAULT, OsExcHardFault);
53     OS_SET_VECTOR(OS_EXC_MPU_FAULT, OsExcMemFault);
54     OS_SET_VECTOR(OS_EXC_BUS_FAULT, OsExcBusFault);
55     OS_SET_VECTOR(OS_EXC_USAGE_FAULT, OsExcUsageFault);
56     g_excTrap = (OsVoidFunc)OsExcSvcCall;
57     OsScheduleInit();
58     OS_SET_VECTOR(OS_EXC_SYS_TICK, OsTickIsr);
59     // 将Tick的优先级置为最低
60     NVIC_SET_EXC_PRI(OS_EXC_SYS_TICK, OS_HWI_PRI_LOWEST);
61 
62     /* 用户中断向量表初始化 */
63     for (loop = OS_MX_SYS_VECTOR_CNT; loop < OS_MX_VECTOR_CNT; loop++) {
64         g_hwiTable[loop] = OsInterrupt;
65     }
66 
67     /* 中断向量表定位 */
68     *(volatile U32 *)OS_NVIC_VTOR = (U32)(uintptr_t)g_hwiTable;
69     /*
70      * 访问钥匙:任何对该寄存器的写操作都必须同时把0x05FA写入此段,否则写操作被忽略
71      * 位段10:8为优先级分组
72      */
73     *(volatile U32 *)OS_NVIC_AIRCR = (OS_NVIC_AIRCR_REG_ACCESS_PSW |
74                                       (OS_NVIC_AIRCR_PRIGROUP << OS_NVIC_AIRCR_PRIGOUP_BIT_OFFSET));
75 }
76 
77 /*
78  * 描述:默认外部中断处理函数
79  */
OsInterrupt(void)80 OS_SEC_TEXT void OsInterrupt(void)
81 {
82     HwiHandle hwiNum;
83     uintptr_t intSave;
84 
85     /* 操作basepri 设置成关中断 */
86     intSave = PRT_HwiLock();
87     UNI_FLAG |= OS_FLG_HWI_ACTIVE;
88     g_intCount++;
89 
90     /* 取外部中断号,中断号减去系统中断号 */
91     hwiNum = OsIntNumGet() - OS_MX_SYS_VECTOR_CNT;
92 #ifdef OS_OPTION_HWI_MAX_NUM_CONFIG
93     if (hwiNum > g_hwiMaxNumConfig) {
94         PRT_HwiRestore(intSave);
95 	return;
96     }
97 #endif
98     OsTskHighestSet();
99 
100     (void)PRT_HwiUnLock();
101     // ISR执行(这里一处开中断)
102     OsHwiHookDispatcher(hwiNum);
103 
104     (void)PRT_HwiLock();
105 
106     g_intCount--;
107 
108     if (g_intCount == 0) {
109         UNI_FLAG &= ~OS_FLG_HWI_ACTIVE;
110     }
111 
112     /* 恢复 basepri */
113     PRT_HwiRestore(intSave);
114 
115     if ((UNI_FLAG & OS_FLG_TSK_REQ) != 0) {
116         OsHwiTrap();
117     }
118 }
119 
120 /*
121  * 描述:硬中断模式设置
122  */
OsHwiPrioritySet(HwiHandle hwiNum,HwiPrior hwiPrio)123 OS_SEC_L4_TEXT void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio)
124 {
125     /* 设置优先级,当前芯片高4位有效,左移4位 */
126     NVIC_SET_IRQ_PRI(hwiNum, OS_HWI_GET_HWI_PRIO(hwiPrio));
127 }
128 
OsHwiPriorityGet(HwiHandle hwiNum)129 OS_SEC_L4_TEXT U32 OsHwiPriorityGet(HwiHandle hwiNum)
130 {
131     return (U32)OS_HWI_GET_USER_PRIO((*((volatile U8 *)((uintptr_t)OS_NVIC_PRI_BASE + (hwiNum)))));
132 }
133 
134 /*
135  * 描述:使能指定中断号
136  */
PRT_HwiEnable(HwiHandle hwiNum)137 OS_SEC_L2_TEXT U32 PRT_HwiEnable(HwiHandle hwiNum)
138 {
139     uintptr_t intSave;
140 
141     if (hwiNum > OS_HWI_MAX) {
142         return OS_ERRNO_HWI_NUM_INVALID;
143     }
144 
145     intSave = PRT_HwiLock();
146 
147     NVIC_SET_IRQ(hwiNum);
148     PRT_HwiRestore(intSave);
149 
150     return OS_OK;
151 }
152 
153 /*
154  * 描述:清除所有的中断请求位
155  */
PRT_HwiClearAllPending(void)156 OS_SEC_L2_TEXT void PRT_HwiClearAllPending(void)
157 {
158     uintptr_t intSave;
159     U32 loop;
160 
161     intSave = PRT_HwiLock();
162 
163     for (loop = 0; loop < OS_HWI_CLRPEND_REG_NUM; loop += sizeof(U32)) {
164         *(volatile U32 *)((uintptr_t)OS_NVIC_CLRPEND_BASE + loop) = OS_MAX_U32;
165     }
166     PRT_HwiRestore(intSave);
167     return;
168 }
169 
170 /*
171  * 描述:清除单个硬中断的Pending位
172  */
PRT_HwiClearPendingBit(HwiHandle hwiNum)173 OS_SEC_L2_TEXT U32 PRT_HwiClearPendingBit(HwiHandle hwiNum)
174 {
175     uintptr_t intSave;
176     if (hwiNum > OS_HWI_MAX) {
177         return OS_ERRNO_HWI_NUM_INVALID;
178     }
179 
180     intSave = PRT_HwiLock();
181     NVIC_CLR_IRQ_PEND(hwiNum);
182     PRT_HwiRestore(intSave);
183     return OS_OK;
184 }
185 
186 /*
187  * 描述:触发指定硬中断号
188  */
PRT_HwiTrigger(U32 dstCore,HwiHandle hwiNum)189 OS_SEC_L2_TEXT U32 PRT_HwiTrigger(U32 dstCore, HwiHandle hwiNum)
190 {
191     uintptr_t intSave;
192 
193     if (hwiNum > OS_HWI_MAX) {
194         return OS_ERRNO_HWI_NUM_INVALID;
195     }
196 
197     if (OsGetHwThreadId() != dstCore) {
198         return OS_ERRNO_HWI_CORE_ID_INVALID;
199     }
200 
201     intSave = PRT_HwiLock();
202 
203     NVIC_SET_IRQ_PEND(hwiNum);
204 
205     PRT_HwiRestore(intSave);
206 
207     return OS_OK;
208 }
209 
210 /*
211  * 描述:禁止指定中断号
212  */
PRT_HwiDisable(HwiHandle hwiNum)213 OS_SEC_L2_TEXT U32 PRT_HwiDisable(HwiHandle hwiNum)
214 {
215     uintptr_t intSave;
216 
217     if (hwiNum > OS_HWI_MAX) {
218         return OS_ERRNO_HWI_NUM_INVALID;
219     }
220 
221     intSave = PRT_HwiLock();
222 
223     NVIC_CLR_IRQ(hwiNum);
224     PRT_HwiRestore(intSave);
225 
226     return OS_OK;
227 }
228 
PRT_HwiDelExitHook(HwiExitHook hook)229 OS_SEC_L4_TEXT U32 PRT_HwiDelExitHook(HwiExitHook hook)
230 {
231     return OsHookDel(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
232 }
PRT_HwiAddExitHook(HwiExitHook hook)233 OS_SEC_L4_TEXT U32 PRT_HwiAddExitHook(HwiExitHook hook)
234 {
235     return OsHookAdd(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
236 }
PRT_HwiDelEntryHook(HwiEntryHook hook)237 OS_SEC_L4_TEXT U32 PRT_HwiDelEntryHook(HwiEntryHook hook)
238 {
239     return OsHookDel(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
240 }
PRT_HwiAddEntryHook(HwiEntryHook hook)241 OS_SEC_L4_TEXT U32 PRT_HwiAddEntryHook(HwiEntryHook hook)
242 {
243     return OsHookAdd(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
244 }
245