154568cb3Sopenharmony_ci/*
254568cb3Sopenharmony_ci * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
354568cb3Sopenharmony_ci *
454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2.
554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2.
654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at:
754568cb3Sopenharmony_ci *          http://license.coscl.org.cn/MulanPSL2
854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details.
1254568cb3Sopenharmony_ci * Create: 2009-12-22
1354568cb3Sopenharmony_ci * Description: Hardware interrupt implementation
1454568cb3Sopenharmony_ci */
1554568cb3Sopenharmony_ci#include "prt_hook_external.h"
1654568cb3Sopenharmony_ci#include "prt_lib_external.h"
1754568cb3Sopenharmony_ci#include "prt_task_external.h"
1854568cb3Sopenharmony_ci#include "prt_hwi_internal.h"
1954568cb3Sopenharmony_ci
2054568cb3Sopenharmony_ci#if defined(OS_OPTION_HWI_MAX_NUM_CONFIG)
2154568cb3Sopenharmony_ciOS_SEC_BSS U32 g_hwiMaxNumConfig;
2254568cb3Sopenharmony_ci#endif
2354568cb3Sopenharmony_ciOS_SEC_BSS OsVoidFunc g_excTrap;
2454568cb3Sopenharmony_ci/*
2554568cb3Sopenharmony_ci * 重定位以后的向量表,
2654568cb3Sopenharmony_ci * 其最后一个四字节表示当前运行的中断号,初始化系统定义异常向量,以便初始化阶段异常接管
2754568cb3Sopenharmony_ci */
2854568cb3Sopenharmony_ciVEC_SEC_DATA HwiPubintFunc g_hwiTable[OS_MX_VECTOR_CNT + 1] = {
2954568cb3Sopenharmony_ci    (HwiPubintFunc)MSTACK_VECTOR,
3054568cb3Sopenharmony_ci    (HwiPubintFunc)OsResetVector,
3154568cb3Sopenharmony_ci};
3254568cb3Sopenharmony_ci
3354568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsScheduleInit(void)
3454568cb3Sopenharmony_ci{
3554568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_PEND_SV, OsPendSv);
3654568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_SVC_CALL, OsSvchandler);
3754568cb3Sopenharmony_ci
3854568cb3Sopenharmony_ci    NVIC_SET_EXC_PRI(OS_EXC_PEND_SV, OS_HWI_PRI_LOWEST);
3954568cb3Sopenharmony_ci    NVIC_SET_EXC_PRI(OS_EXC_SVC_CALL, OS_HWI_PRI_HIGHEST);
4054568cb3Sopenharmony_ci}
4154568cb3Sopenharmony_ci
4254568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsHwiGICInit(void)
4354568cb3Sopenharmony_ci{
4454568cb3Sopenharmony_ci    U32 loop;
4554568cb3Sopenharmony_ci    /* 系统中断向量表初始化 */
4654568cb3Sopenharmony_ci    for (loop = 0; loop < OS_MX_SYS_VECTOR_CNT; loop++) {
4754568cb3Sopenharmony_ci        g_hwiTable[loop] = (HwiPubintFunc)OsHwiDefaultHandler;
4854568cb3Sopenharmony_ci    }
4954568cb3Sopenharmony_ci    OS_SET_VECTOR(0, (HwiPubintFunc)MSTACK_VECTOR);
5054568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_RESET, OsResetVector);
5154568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_NMI, OsExcNmi);
5254568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_HARD_FAULT, OsExcHardFault);
5354568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_MPU_FAULT, OsExcMemFault);
5454568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_BUS_FAULT, OsExcBusFault);
5554568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_USAGE_FAULT, OsExcUsageFault);
5654568cb3Sopenharmony_ci    g_excTrap = (OsVoidFunc)OsExcSvcCall;
5754568cb3Sopenharmony_ci    OsScheduleInit();
5854568cb3Sopenharmony_ci    OS_SET_VECTOR(OS_EXC_SYS_TICK, OsTickIsr);
5954568cb3Sopenharmony_ci    // 将Tick的优先级置为最低
6054568cb3Sopenharmony_ci    NVIC_SET_EXC_PRI(OS_EXC_SYS_TICK, OS_HWI_PRI_LOWEST);
6154568cb3Sopenharmony_ci
6254568cb3Sopenharmony_ci    /* 用户中断向量表初始化 */
6354568cb3Sopenharmony_ci    for (loop = OS_MX_SYS_VECTOR_CNT; loop < OS_MX_VECTOR_CNT; loop++) {
6454568cb3Sopenharmony_ci        g_hwiTable[loop] = OsInterrupt;
6554568cb3Sopenharmony_ci    }
6654568cb3Sopenharmony_ci
6754568cb3Sopenharmony_ci    /* 中断向量表定位 */
6854568cb3Sopenharmony_ci    *(volatile U32 *)OS_NVIC_VTOR = (U32)(uintptr_t)g_hwiTable;
6954568cb3Sopenharmony_ci    /*
7054568cb3Sopenharmony_ci     * 访问钥匙:任何对该寄存器的写操作都必须同时把0x05FA写入此段,否则写操作被忽略
7154568cb3Sopenharmony_ci     * 位段10:8为优先级分组
7254568cb3Sopenharmony_ci     */
7354568cb3Sopenharmony_ci    *(volatile U32 *)OS_NVIC_AIRCR = (OS_NVIC_AIRCR_REG_ACCESS_PSW |
7454568cb3Sopenharmony_ci                                      (OS_NVIC_AIRCR_PRIGROUP << OS_NVIC_AIRCR_PRIGOUP_BIT_OFFSET));
7554568cb3Sopenharmony_ci}
7654568cb3Sopenharmony_ci
7754568cb3Sopenharmony_ci/*
7854568cb3Sopenharmony_ci * 描述:默认外部中断处理函数
7954568cb3Sopenharmony_ci */
8054568cb3Sopenharmony_ciOS_SEC_TEXT void OsInterrupt(void)
8154568cb3Sopenharmony_ci{
8254568cb3Sopenharmony_ci    HwiHandle hwiNum;
8354568cb3Sopenharmony_ci    uintptr_t intSave;
8454568cb3Sopenharmony_ci
8554568cb3Sopenharmony_ci    /* 操作basepri 设置成关中断 */
8654568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
8754568cb3Sopenharmony_ci    UNI_FLAG |= OS_FLG_HWI_ACTIVE;
8854568cb3Sopenharmony_ci    g_intCount++;
8954568cb3Sopenharmony_ci
9054568cb3Sopenharmony_ci    /* 取外部中断号,中断号减去系统中断号 */
9154568cb3Sopenharmony_ci    hwiNum = OsIntNumGet() - OS_MX_SYS_VECTOR_CNT;
9254568cb3Sopenharmony_ci#ifdef OS_OPTION_HWI_MAX_NUM_CONFIG
9354568cb3Sopenharmony_ci    if (hwiNum > g_hwiMaxNumConfig) {
9454568cb3Sopenharmony_ci        PRT_HwiRestore(intSave);
9554568cb3Sopenharmony_ci	return;
9654568cb3Sopenharmony_ci    }
9754568cb3Sopenharmony_ci#endif
9854568cb3Sopenharmony_ci    OsTskHighestSet();
9954568cb3Sopenharmony_ci
10054568cb3Sopenharmony_ci    (void)PRT_HwiUnLock();
10154568cb3Sopenharmony_ci    // ISR执行(这里一处开中断)
10254568cb3Sopenharmony_ci    OsHwiHookDispatcher(hwiNum);
10354568cb3Sopenharmony_ci
10454568cb3Sopenharmony_ci    (void)PRT_HwiLock();
10554568cb3Sopenharmony_ci
10654568cb3Sopenharmony_ci    g_intCount--;
10754568cb3Sopenharmony_ci
10854568cb3Sopenharmony_ci    if (g_intCount == 0) {
10954568cb3Sopenharmony_ci        UNI_FLAG &= ~OS_FLG_HWI_ACTIVE;
11054568cb3Sopenharmony_ci    }
11154568cb3Sopenharmony_ci
11254568cb3Sopenharmony_ci    /* 恢复 basepri */
11354568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
11454568cb3Sopenharmony_ci
11554568cb3Sopenharmony_ci    if ((UNI_FLAG & OS_FLG_TSK_REQ) != 0) {
11654568cb3Sopenharmony_ci        OsHwiTrap();
11754568cb3Sopenharmony_ci    }
11854568cb3Sopenharmony_ci}
11954568cb3Sopenharmony_ci
12054568cb3Sopenharmony_ci/*
12154568cb3Sopenharmony_ci * 描述:硬中断模式设置
12254568cb3Sopenharmony_ci */
12354568cb3Sopenharmony_ciOS_SEC_L4_TEXT void OsHwiPrioritySet(HwiHandle hwiNum, HwiPrior hwiPrio)
12454568cb3Sopenharmony_ci{
12554568cb3Sopenharmony_ci    /* 设置优先级,当前芯片高4位有效,左移4位 */
12654568cb3Sopenharmony_ci    NVIC_SET_IRQ_PRI(hwiNum, OS_HWI_GET_HWI_PRIO(hwiPrio));
12754568cb3Sopenharmony_ci}
12854568cb3Sopenharmony_ci
12954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 OsHwiPriorityGet(HwiHandle hwiNum)
13054568cb3Sopenharmony_ci{
13154568cb3Sopenharmony_ci    return (U32)OS_HWI_GET_USER_PRIO((*((volatile U8 *)((uintptr_t)OS_NVIC_PRI_BASE + (hwiNum)))));
13254568cb3Sopenharmony_ci}
13354568cb3Sopenharmony_ci
13454568cb3Sopenharmony_ci/*
13554568cb3Sopenharmony_ci * 描述:使能指定中断号
13654568cb3Sopenharmony_ci */
13754568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiEnable(HwiHandle hwiNum)
13854568cb3Sopenharmony_ci{
13954568cb3Sopenharmony_ci    uintptr_t intSave;
14054568cb3Sopenharmony_ci
14154568cb3Sopenharmony_ci    if (hwiNum > OS_HWI_MAX) {
14254568cb3Sopenharmony_ci        return OS_ERRNO_HWI_NUM_INVALID;
14354568cb3Sopenharmony_ci    }
14454568cb3Sopenharmony_ci
14554568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
14654568cb3Sopenharmony_ci
14754568cb3Sopenharmony_ci    NVIC_SET_IRQ(hwiNum);
14854568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
14954568cb3Sopenharmony_ci
15054568cb3Sopenharmony_ci    return OS_OK;
15154568cb3Sopenharmony_ci}
15254568cb3Sopenharmony_ci
15354568cb3Sopenharmony_ci/*
15454568cb3Sopenharmony_ci * 描述:清除所有的中断请求位
15554568cb3Sopenharmony_ci */
15654568cb3Sopenharmony_ciOS_SEC_L2_TEXT void PRT_HwiClearAllPending(void)
15754568cb3Sopenharmony_ci{
15854568cb3Sopenharmony_ci    uintptr_t intSave;
15954568cb3Sopenharmony_ci    U32 loop;
16054568cb3Sopenharmony_ci
16154568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
16254568cb3Sopenharmony_ci
16354568cb3Sopenharmony_ci    for (loop = 0; loop < OS_HWI_CLRPEND_REG_NUM; loop += sizeof(U32)) {
16454568cb3Sopenharmony_ci        *(volatile U32 *)((uintptr_t)OS_NVIC_CLRPEND_BASE + loop) = OS_MAX_U32;
16554568cb3Sopenharmony_ci    }
16654568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
16754568cb3Sopenharmony_ci    return;
16854568cb3Sopenharmony_ci}
16954568cb3Sopenharmony_ci
17054568cb3Sopenharmony_ci/*
17154568cb3Sopenharmony_ci * 描述:清除单个硬中断的Pending位
17254568cb3Sopenharmony_ci */
17354568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiClearPendingBit(HwiHandle hwiNum)
17454568cb3Sopenharmony_ci{
17554568cb3Sopenharmony_ci    uintptr_t intSave;
17654568cb3Sopenharmony_ci    if (hwiNum > OS_HWI_MAX) {
17754568cb3Sopenharmony_ci        return OS_ERRNO_HWI_NUM_INVALID;
17854568cb3Sopenharmony_ci    }
17954568cb3Sopenharmony_ci
18054568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
18154568cb3Sopenharmony_ci    NVIC_CLR_IRQ_PEND(hwiNum);
18254568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
18354568cb3Sopenharmony_ci    return OS_OK;
18454568cb3Sopenharmony_ci}
18554568cb3Sopenharmony_ci
18654568cb3Sopenharmony_ci/*
18754568cb3Sopenharmony_ci * 描述:触发指定硬中断号
18854568cb3Sopenharmony_ci */
18954568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiTrigger(U32 dstCore, HwiHandle hwiNum)
19054568cb3Sopenharmony_ci{
19154568cb3Sopenharmony_ci    uintptr_t intSave;
19254568cb3Sopenharmony_ci
19354568cb3Sopenharmony_ci    if (hwiNum > OS_HWI_MAX) {
19454568cb3Sopenharmony_ci        return OS_ERRNO_HWI_NUM_INVALID;
19554568cb3Sopenharmony_ci    }
19654568cb3Sopenharmony_ci
19754568cb3Sopenharmony_ci    if (OsGetHwThreadId() != dstCore) {
19854568cb3Sopenharmony_ci        return OS_ERRNO_HWI_CORE_ID_INVALID;
19954568cb3Sopenharmony_ci    }
20054568cb3Sopenharmony_ci
20154568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
20254568cb3Sopenharmony_ci
20354568cb3Sopenharmony_ci    NVIC_SET_IRQ_PEND(hwiNum);
20454568cb3Sopenharmony_ci
20554568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
20654568cb3Sopenharmony_ci
20754568cb3Sopenharmony_ci    return OS_OK;
20854568cb3Sopenharmony_ci}
20954568cb3Sopenharmony_ci
21054568cb3Sopenharmony_ci/*
21154568cb3Sopenharmony_ci * 描述:禁止指定中断号
21254568cb3Sopenharmony_ci */
21354568cb3Sopenharmony_ciOS_SEC_L2_TEXT U32 PRT_HwiDisable(HwiHandle hwiNum)
21454568cb3Sopenharmony_ci{
21554568cb3Sopenharmony_ci    uintptr_t intSave;
21654568cb3Sopenharmony_ci
21754568cb3Sopenharmony_ci    if (hwiNum > OS_HWI_MAX) {
21854568cb3Sopenharmony_ci        return OS_ERRNO_HWI_NUM_INVALID;
21954568cb3Sopenharmony_ci    }
22054568cb3Sopenharmony_ci
22154568cb3Sopenharmony_ci    intSave = PRT_HwiLock();
22254568cb3Sopenharmony_ci
22354568cb3Sopenharmony_ci    NVIC_CLR_IRQ(hwiNum);
22454568cb3Sopenharmony_ci    PRT_HwiRestore(intSave);
22554568cb3Sopenharmony_ci
22654568cb3Sopenharmony_ci    return OS_OK;
22754568cb3Sopenharmony_ci}
22854568cb3Sopenharmony_ci
22954568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiDelExitHook(HwiExitHook hook)
23054568cb3Sopenharmony_ci{
23154568cb3Sopenharmony_ci    return OsHookDel(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
23254568cb3Sopenharmony_ci}
23354568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiAddExitHook(HwiExitHook hook)
23454568cb3Sopenharmony_ci{
23554568cb3Sopenharmony_ci    return OsHookAdd(OS_HOOK_HWI_EXIT, (OsVoidFunc)hook);
23654568cb3Sopenharmony_ci}
23754568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiDelEntryHook(HwiEntryHook hook)
23854568cb3Sopenharmony_ci{
23954568cb3Sopenharmony_ci    return OsHookDel(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
24054568cb3Sopenharmony_ci}
24154568cb3Sopenharmony_ciOS_SEC_L4_TEXT U32 PRT_HwiAddEntryHook(HwiEntryHook hook)
24254568cb3Sopenharmony_ci{
24354568cb3Sopenharmony_ci    return OsHookAdd(OS_HOOK_HWI_ENTRY, (OsVoidFunc)hook);
24454568cb3Sopenharmony_ci}
245