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: HOOK模块的内部头文件
1454568cb3Sopenharmony_ci */
1554568cb3Sopenharmony_ci#ifndef PRT_HOOK_EXTERNAL_H
1654568cb3Sopenharmony_ci#define PRT_HOOK_EXTERNAL_H
1754568cb3Sopenharmony_ci
1854568cb3Sopenharmony_ci#include "prt_hook.h"
1954568cb3Sopenharmony_ci#include "prt_sys.h"
2054568cb3Sopenharmony_ci
2154568cb3Sopenharmony_ci/* 限制:参数类型不能为U64大于uintptr_t */
2254568cb3Sopenharmony_citypedef void (*OsFunPara0)(void);
2354568cb3Sopenharmony_citypedef void (*OsFunPara1)(uintptr_t);
2454568cb3Sopenharmony_citypedef void (*OsFunPara2)(uintptr_t, uintptr_t);
2554568cb3Sopenharmony_citypedef void (*OsFunPara3)(uintptr_t, uintptr_t, uintptr_t);
2654568cb3Sopenharmony_citypedef void (*OsFunPara4)(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
2754568cb3Sopenharmony_citypedef void (*OsFunPara5)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
2854568cb3Sopenharmony_ci
2954568cb3Sopenharmony_ci/*
3054568cb3Sopenharmony_ci * 内核钩子管理原则
3154568cb3Sopenharmony_ci * 1)服务于内核模块的钩子才可纳入钩子模块统一管理,例如补丁、shell模块的钩子就不适合。
3254568cb3Sopenharmony_ci * 内核模块指mem,kernel,ipc,服务于内核的arch。
3354568cb3Sopenharmony_ci * 2)没有返回值,没有输出参数的钩子才可纳入钩子模块统一管理。
3454568cb3Sopenharmony_ci */
3554568cb3Sopenharmony_ci#define OS_MHOOK_BOUNDARY ((U32)1)
3654568cb3Sopenharmony_ci
3754568cb3Sopenharmony_ci#define OS_MHOOK_NODE_DEAD ((OsVoidFunc)2)
3854568cb3Sopenharmony_ci
3954568cb3Sopenharmony_ci// 除了OS_HOOK_EMPTY和OS_MHOOK_BOUNDARY外,都是有效钩子
4054568cb3Sopenharmony_ci#define OS_MHOOK_IS_VALID(hook) ((uintptr_t)(hook) > OS_MHOOK_BOUNDARY)
4154568cb3Sopenharmony_ci
4254568cb3Sopenharmony_ci#define OS_MHOOK_NOT_BOUNDARY(hook) ((uintptr_t)(hook) != OS_MHOOK_BOUNDARY)
4354568cb3Sopenharmony_ci
4454568cb3Sopenharmony_ciOS_SEC_ALW_INLINE INLINE bool OsMhookBoundaryCheck(OsVoidFunc hook)
4554568cb3Sopenharmony_ci{
4654568cb3Sopenharmony_ci    return ((uintptr_t)hook <= OS_MHOOK_BOUNDARY);
4754568cb3Sopenharmony_ci}
4854568cb3Sopenharmony_ci
4954568cb3Sopenharmony_ciOS_SEC_ALW_INLINE INLINE bool OsMhookValidCheck(OsVoidFunc hook)
5054568cb3Sopenharmony_ci{
5154568cb3Sopenharmony_ci    return (hook != OS_MHOOK_NODE_DEAD);
5254568cb3Sopenharmony_ci}
5354568cb3Sopenharmony_ci
5454568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, list)                        \
5554568cb3Sopenharmony_ci    do {                                                                         \
5654568cb3Sopenharmony_ci        OsVoidFunc *tmp_ = hook;                                                 \
5754568cb3Sopenharmony_ci        while (!OsMhookBoundaryCheck((OsVoidFunc)((pfn) = (funcType)(*tmp_)))) { \
5854568cb3Sopenharmony_ci            if (OsMhookValidCheck((OsVoidFunc)(pfn))) {                          \
5954568cb3Sopenharmony_ci                (list);                                                          \
6054568cb3Sopenharmony_ci            }                                                                    \
6154568cb3Sopenharmony_ci            tmp_++;                                                              \
6254568cb3Sopenharmony_ci        }                                                                        \
6354568cb3Sopenharmony_ci    } while (0)
6454568cb3Sopenharmony_ci
6554568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE(hookType, funcType, list)              \
6654568cb3Sopenharmony_ci    do {                                                         \
6754568cb3Sopenharmony_ci        OsVoidFunc *hook = g_hookCb[(hookType)].mulHook;         \
6854568cb3Sopenharmony_ci        funcType pfn;                                            \
6954568cb3Sopenharmony_ci        if (hook != NULL) {                                      \
7054568cb3Sopenharmony_ci            OS_MHOOK_ACTIVATE_PROC(hook, funcType, pfn, (list)); \
7154568cb3Sopenharmony_ci        }                                                        \
7254568cb3Sopenharmony_ci    } while (0)
7354568cb3Sopenharmony_ci
7454568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE(hookType, funcType, list)            \
7554568cb3Sopenharmony_ci    do {                                                       \
7654568cb3Sopenharmony_ci        funcType pfn = (funcType)g_hookCb[(hookType)].sigHook; \
7754568cb3Sopenharmony_ci        if (pfn != NULL)                                       \
7854568cb3Sopenharmony_ci            (list);                                            \
7954568cb3Sopenharmony_ci    } while (0)
8054568cb3Sopenharmony_ci
8154568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA0(hookType) OS_MHOOK_ACTIVATE((hookType), OsFunPara0, pfn())
8254568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA1(hookType, arg0) OS_MHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0)))
8354568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_MHOOK_ACTIVATE((hookType), \
8454568cb3Sopenharmony_ci    OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1)))
8554568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_MHOOK_ACTIVATE((hookType), \
8654568cb3Sopenharmony_ci    OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2)))
8754568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \
8854568cb3Sopenharmony_ci    OS_MHOOK_ACTIVATE((hookType),                                 \
8954568cb3Sopenharmony_ci    OsFunPara4, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3)))
9054568cb3Sopenharmony_ci#define OS_MHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \
9154568cb3Sopenharmony_ci    OS_MHOOK_ACTIVATE((hookType), OsFunPara5,                           \
9254568cb3Sopenharmony_ci    pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4)))
9354568cb3Sopenharmony_ci
9454568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA0(hookType) OS_SHOOK_ACTIVATE((hookType), OsFunPara0, pfn())
9554568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA1(hookType, arg0) OS_SHOOK_ACTIVATE((hookType), OsFunPara1, pfn((uintptr_t)(arg0)))
9654568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA2(hookType, arg0, arg1) OS_SHOOK_ACTIVATE((hookType), \
9754568cb3Sopenharmony_ci    OsFunPara2, pfn((uintptr_t)(arg0), (uintptr_t)(arg1)))
9854568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA3(hookType, arg0, arg1, arg2) OS_SHOOK_ACTIVATE((hookType), \
9954568cb3Sopenharmony_ci    OsFunPara3, pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2)))
10054568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA4(hookType, arg0, arg1, arg2, arg3) \
10154568cb3Sopenharmony_ci    OS_SHOOK_ACTIVATE((hookType), OsFunPara4,                     \
10254568cb3Sopenharmony_ci    pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3)))
10354568cb3Sopenharmony_ci#define OS_SHOOK_ACTIVATE_PARA5(hookType, arg0, arg1, arg2, arg3, arg4) \
10454568cb3Sopenharmony_ci    OS_SHOOK_ACTIVATE((hookType), OsFunPara5,                           \
10554568cb3Sopenharmony_ci    pfn((uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), (uintptr_t)(arg3), (uintptr_t)(arg4)))
10654568cb3Sopenharmony_ci
10754568cb3Sopenharmony_ci#define HOOK_ADD_IRQ_LOCK(intSave) \
10854568cb3Sopenharmony_ci    do {                           \
10954568cb3Sopenharmony_ci        (intSave) = PRT_HwiLock(); \
11054568cb3Sopenharmony_ci    } while (0)
11154568cb3Sopenharmony_ci#define HOOK_ADD_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave))
11254568cb3Sopenharmony_ci
11354568cb3Sopenharmony_ci#define HOOK_DEL_IRQ_LOCK(intSave) \
11454568cb3Sopenharmony_ci    do {                           \
11554568cb3Sopenharmony_ci        (intSave) = PRT_HwiLock(); \
11654568cb3Sopenharmony_ci    } while (0)
11754568cb3Sopenharmony_ci#define HOOK_DEL_IRQ_UNLOCK(intSave) PRT_HwiRestore((intSave))
11854568cb3Sopenharmony_ci
11954568cb3Sopenharmony_cienum {
12054568cb3Sopenharmony_ci    OS_HOOK_TICK_ENTRY = OS_HOOK_TYPE_NUM,
12154568cb3Sopenharmony_ci    OS_HOOK_TICK_EXIT,
12254568cb3Sopenharmony_ci    OS_HOOK_FIRST_TIME_SWH,
12354568cb3Sopenharmony_ci    OS_HOOK_TSK_MON, /* TSKMON钩子 */
12454568cb3Sopenharmony_ci    OS_HOOK_CPUP_WARN, /* CPUP告警钩子 */
12554568cb3Sopenharmony_ci    OS_HOOK_ERR_REG, /* 错误处理钩子 */
12654568cb3Sopenharmony_ci    OS_HOOK_IDLE_PREFIX, /* IDLE前置钩子 */
12754568cb3Sopenharmony_ci    OS_HOOK_MEM_DAMAGE, /* 踩内存处理钩子 */
12854568cb3Sopenharmony_ci
12954568cb3Sopenharmony_ci    OS_HOOK_TYPE_TOTAL
13054568cb3Sopenharmony_ci};
13154568cb3Sopenharmony_ci
13254568cb3Sopenharmony_ci#define OS_SHOOK_TYPE_START ((U32)OS_HOOK_TSK_MON)
13354568cb3Sopenharmony_ci
13454568cb3Sopenharmony_cienum HookChgType {
13554568cb3Sopenharmony_ci    HOOK_ADD_FIRST,
13654568cb3Sopenharmony_ci    HOOK_DEL_LAST
13754568cb3Sopenharmony_ci};
13854568cb3Sopenharmony_ci
13954568cb3Sopenharmony_ciunion TagMhookCb {
14054568cb3Sopenharmony_ci    // 在初始化阶段复用为钩子注册数目
14154568cb3Sopenharmony_ci    uintptr_t num;
14254568cb3Sopenharmony_ci    // 单钩子
14354568cb3Sopenharmony_ci    OsVoidFunc sigHook;
14454568cb3Sopenharmony_ci    OsVoidFunc *mulHook;
14554568cb3Sopenharmony_ci};
14654568cb3Sopenharmony_ci
14754568cb3Sopenharmony_citypedef U32(*OsHookChgFunc)(U32 hookType, enum HookChgType chgType);
14854568cb3Sopenharmony_ci
14954568cb3Sopenharmony_ciextern union TagMhookCb g_hookCb[OS_HOOK_TYPE_TOTAL];
15054568cb3Sopenharmony_ci
15154568cb3Sopenharmony_citypedef void *(*MemAllocHook)(enum MoudleId mid, U8 ptNo, U32 size);
15254568cb3Sopenharmony_ciextern MemAllocHook g_osMemAlloc;
15354568cb3Sopenharmony_ci
15454568cb3Sopenharmony_ci/*
15554568cb3Sopenharmony_ci * 多钩子添加内部接口
15654568cb3Sopenharmony_ci */
15754568cb3Sopenharmony_ciextern U32 OsMhookAdd(U32 hookType, OsVoidFunc hook);
15854568cb3Sopenharmony_ci
15954568cb3Sopenharmony_ci/*
16054568cb3Sopenharmony_ci * 多钩子删除内部接口
16154568cb3Sopenharmony_ci */
16254568cb3Sopenharmony_ciextern U32 OsMhookDel(U32 hookType, OsVoidFunc hook);
16354568cb3Sopenharmony_ci
16454568cb3Sopenharmony_ci/*
16554568cb3Sopenharmony_ci * 钩子添加内部接口
16654568cb3Sopenharmony_ci */
16754568cb3Sopenharmony_ciextern U32 OsHookAdd(enum HookType hookType, OsVoidFunc hook);
16854568cb3Sopenharmony_ci
16954568cb3Sopenharmony_ci/*
17054568cb3Sopenharmony_ci * 钩子删除内部接口
17154568cb3Sopenharmony_ci */
17254568cb3Sopenharmony_ciextern U32 OsHookDel(enum HookType hookType, OsVoidFunc hook);
17354568cb3Sopenharmony_ci
17454568cb3Sopenharmony_ci/*
17554568cb3Sopenharmony_ci * 多钩子注册内部接口, 为了与原有规格兼容,传入NULL表示删除
17654568cb3Sopenharmony_ci */
17754568cb3Sopenharmony_ciextern U32 OsShookReg(U32 hookType, OsVoidFunc hook);
17854568cb3Sopenharmony_ci
17954568cb3Sopenharmony_ci/*
18054568cb3Sopenharmony_ci * 在注册阶段,不同模块通过osMhookReserve接口预留钩子,不影响用户注册钩子数
18154568cb3Sopenharmony_ci * 仅在register阶段使用
18254568cb3Sopenharmony_ci */
18354568cb3Sopenharmony_ciextern void OsMhookReserve(U32 hookType, U32 incCnt);
18454568cb3Sopenharmony_ci
18554568cb3Sopenharmony_ci#endif /* PRT_HOOK_EXTERNAL_H */
186