diff --git a/src/arch/riscv64/port/process.c b/src/arch/riscv64/port/process.c
index 88647fd0fda4eba8020693c6f72208cda75fe9fb..3e46d46777fa6e3a1471ace4dc91e7f2155cad8e 100644
--- a/src/arch/riscv64/port/process.c
+++ b/src/arch/riscv64/port/process.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include
#include
@@ -71,12 +72,16 @@ NX_PRIVATE NX_Error NX_HalProcessSwitchPageTable(void *pageTableVir)
void NX_HalProcessSyscallDispatch(NX_HalTrapFrame *frame)
{
- NX_SyscallWithArgHandler handler = (NX_SyscallWithArgHandler)NX_SyscallGetHandler((NX_SyscallApi)frame->a7);
+ NX_SyscallApi api = frame->a7;
+
+ NX_SyscallWithArgHandler handler = (NX_SyscallWithArgHandler)NX_SyscallGetHandler(api);
NX_ASSERT(handler);
NX_LOG_D("riscv64 syscall api: %x, arg0:%x, arg1:%x, arg2:%x, arg3:%x, arg4:%x, arg5:%x, arg6:%x",
frame->a7, frame->a0, frame->a1, frame->a2, frame->a3, frame->a4, frame->a5, frame->a6);
+ NX_SYSCALL_ENTER_HOOK(api, frame->a0, frame->a1, frame->a2, frame->a3, frame->a4, frame->a5, frame->a6);
+
if (frame->a7 == NX_SYSCALL_SIGNAl_EXIT) /* handle signal exit */
{
NX_HalProcessSignalExit(frame);
@@ -85,12 +90,12 @@ void NX_HalProcessSyscallDispatch(NX_HalTrapFrame *frame)
else
{
frame->a0 = handler(frame->a0, frame->a1, frame->a2, frame->a3, frame->a4, frame->a5, frame->a6);
-
}
frame->a7 = 0; /* clear syscall api */
frame->epc += 4; /* skip ecall instruction */
+ NX_SYSCALL_LEAVE_HOOK(api, frame->a0);
NX_LOG_D("riscv64 syscall return: %x", frame->a0);
}
diff --git a/src/arch/x86/port/process.c b/src/arch/x86/port/process.c
index 40771da7c971a710451459b0a24a21a28c78bf70..f3aca91987bdd3fb5b90d0b497aa9cbfe4b5bc8e 100644
--- a/src/arch/x86/port/process.c
+++ b/src/arch/x86/port/process.c
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -75,7 +76,9 @@ NX_PRIVATE NX_Error NX_HalProcessSwitchPageTable(void *pageTableVir)
void NX_HalProcessSyscallDispatch(NX_HalTrapFrame *frame)
{
- NX_SyscallWithArgHandler handler = (NX_SyscallWithArgHandler)NX_SyscallGetHandler((NX_SyscallApi)frame->eax);
+ NX_SyscallApi api = frame->eax;
+
+ NX_SyscallWithArgHandler handler = (NX_SyscallWithArgHandler)NX_SyscallGetHandler(api);
NX_ASSERT(handler);
/* arg6 saved on the stack */
@@ -84,6 +87,8 @@ void NX_HalProcessSyscallDispatch(NX_HalTrapFrame *frame)
NX_LOG_D("x86 syscall api: %x, arg0:%x, arg1:%x, arg2:%x, arg3:%x, arg4:%x, arg5:%x, arg6:%x",
frame->eax, frame->ebx, frame->ecx, frame->edx, frame->esi, frame->edi, frame->ebp, arg6);
+ NX_SYSCALL_ENTER_HOOK(api, frame->ebx, frame->ecx, frame->edx, frame->esi, frame->edi, frame->ebp, arg6);
+
if (frame->eax == NX_SYSCALL_SIGNAl_EXIT) /* handle signal exit */
{
NX_HalProcessSignalExit(frame);
@@ -92,6 +97,7 @@ void NX_HalProcessSyscallDispatch(NX_HalTrapFrame *frame)
frame->eax = handler(frame->ebx, frame->ecx, frame->edx, frame->esi, frame->edi, frame->ebp, arg6);
+ NX_SYSCALL_LEAVE_HOOK(api, frame->eax);
NX_LOG_D("x86 syscall return: %x", frame->eax);
}
diff --git a/src/include/base/hooks.h b/src/include/base/hooks.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3d6ebe72856ea1b201cfe20e3b1d7b257a40ab7
--- /dev/null
+++ b/src/include/base/hooks.h
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2018-2022, NXOS Development Team
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Contains: Hook system
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-10-10 JasonHu Init
+ */
+
+#ifndef __NXOS_HOOKS_H__
+#define __NXOS_HOOKS_H__
+
+#include
+#include
+#include
+
+#ifdef CONFIG_NX_MAIN_THREAD_HOOK
+void NX_MainThreadHook(void);
+#define NX_MAIN_THREAD_HOOK() NX_MainThreadHook()
+#else
+#define NX_MAIN_THREAD_HOOK()
+#endif
+
+#ifdef CONFIG_NX_STARTUP_HOOK
+void NX_StartupHook(void);
+#define NX_STARTUP_HOOK() NX_StartupHook()
+#else
+#define NX_STARTUP_HOOK()
+#endif
+
+#ifdef CONFIG_NX_CORE_STARTUP_HOOK
+void NX_CoreStartupHook(NX_UArch coreId);
+#define NX_CORE_STARTUP_HOOK(coreID) NX_CoreStartupHook(coreID)
+#else
+#define NX_CORE_STARTUP_HOOK(coreID)
+#endif
+
+#ifdef CONFIG_NX_TICKS_HOOK
+void NX_TicksHook(void);
+#define NX_TICKS_HOOK() NX_TicksHook()
+#else
+#define NX_TICKS_HOOK()
+#endif
+
+#ifdef CONFIG_NX_IDLE_HOOK
+void NX_IdleHook(void);
+#define NX_IDLE_HOOK() NX_IdleHook()
+#else
+#define NX_IDLE_HOOK()
+#endif
+
+#ifdef CONFIG_NX_CONTEXT_SWITCH_HOOK
+void NX_ContextSwitchHook(NX_Thread * prev, NX_Thread * next);
+#define NX_CONTEXT_SWITCH_HOOK(prev, next) NX_ContextSwitchHook(prev, next)
+#else
+#define NX_CONTEXT_SWITCH_HOOK(prev, next)
+#endif
+
+#ifdef CONFIG_NX_PREV_THREAD_HOOK
+void NX_PrevThreadHook(NX_Thread * thread);
+#define NX_PREV_THREAD_HOOK(thread) NX_PrevThreadHook(thread)
+#else
+#define NX_PREV_THREAD_HOOK(thread)
+#endif
+
+#ifdef CONFIG_NX_POST_THREAD_HOOK
+void NX_PostThreadHook(NX_Thread * thread);
+#define NX_POST_THREAD_HOOK(thread) NX_PostThreadHook(thread)
+#else
+#define NX_POST_THREAD_HOOK(thread)
+#endif
+
+#ifdef CONFIG_NX_SYSCALL_ENTER_HOOK
+void NX_SyscallEnterHook(NX_SyscallApi api, NX_UArch arg0, NX_UArch arg1, NX_UArch arg2,
+ NX_UArch arg3, NX_UArch arg4, NX_UArch arg5, NX_UArch arg6);
+#define NX_SYSCALL_ENTER_HOOK(api, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+ NX_SyscallEnterHook(api, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#else
+#define NX_SYSCALL_ENTER_HOOK(api, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+#endif
+
+#ifdef CONFIG_NX_SYSCALL_LEAVE_HOOK
+void NX_SyscallLeaveHook(NX_SyscallApi api, NX_UArch retval);
+#define NX_SYSCALL_LEAVE_HOOK(api, retval) NX_SyscallLeaveHook(api, retval)
+#else
+#define NX_SYSCALL_LEAVE_HOOK(api, retval)
+#endif
+
+#endif /* __NXOS_HOOKS_H__ */
diff --git a/src/init/Kconfig b/src/init/Kconfig
index 6d1162be46ec3c8571ec1b25b67fa0fecc0ba665..94f4e17cc890127750b504dafc960a9a78f159d2 100644
--- a/src/init/Kconfig
+++ b/src/init/Kconfig
@@ -8,7 +8,3 @@ config NX_PLATFORM_NAME
config NX_MULTI_CORES_NR
int "platform CPU core numbers"
default 1
-
-config NX_ENABLE_PLATFORM_MAIN
- bool "Enable call platform main"
- default y
diff --git a/src/init/init.c b/src/init/init.c
index bdb20c09b0b46f3f27ec6002c44f5b2a39f0aa93..0a8e5aa80bb23a4ae222199502e81a137c1e1159 100644
--- a/src/init/init.c
+++ b/src/init/init.c
@@ -14,6 +14,7 @@
#define NX_LOG_NAME "InitCall"
#include
#include
+#include
NX_IMPORT NX_InitCallHandler __NX_InitCallStart[];
NX_IMPORT NX_InitCallHandler __NX_InitCallEnd[];
@@ -39,13 +40,6 @@ void NX_ExitCallInvoke(void)
NX_CallInvoke(__NX_ExitCallStart, __NX_ExitCallEnd);
}
-#ifdef CONFIG_NX_ENABLE_PLATFORM_MAIN
-NX_INTERFACE NX_WEAK_SYM void NX_HalPlatformMain(void)
-{
- NX_LOG_I("Deafult platform main running...\n");
-}
-#endif
-
NX_PRIVATE void CallsEntry(void *arg)
{
NX_InitCallInvoke();
@@ -88,9 +82,7 @@ NX_PRIVATE void CallsEntry(void *arg)
}
#endif /* CONFIG_NX_ENABLE_EXECUTE_USER */
-#ifdef CONFIG_NX_ENABLE_PLATFORM_MAIN
- NX_HalPlatformMain();
-#endif
+ NX_MAIN_THREAD_HOOK();
}
void NX_CallsInit(void)
diff --git a/src/init/main.c b/src/init/main.c
index 274469aaf05704409f73238e474b3ab492851461..b907c10d786fbdda3b2a40056151ce147ba08f02 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
/**
* see http://asciiarts.net
@@ -75,6 +76,10 @@ int NX_Main(NX_UArch coreId)
NX_PANIC("Platfrom init failed!");
}
+ NX_STARTUP_HOOK();
+
+ NX_CORE_STARTUP_HOOK(coreId);
+
ShowLogVersion();
/* init irq */
@@ -117,6 +122,9 @@ int NX_Main(NX_UArch coreId)
else
{
NX_AtomicInc(&gActivedCoreCount);
+
+ NX_CORE_STARTUP_HOOK(coreId);
+
NX_SMP_Stage2(coreId);
}
/* start sched */
diff --git a/src/kernel/Kconfig b/src/kernel/Kconfig
index dcff6e10007d2d0304a232d7f3ad18215cf96562..780453c549bb81d0ffc9a9651b4d9cca102f1e4b 100644
--- a/src/kernel/Kconfig
+++ b/src/kernel/Kconfig
@@ -21,4 +21,55 @@ if NX_DEBUG
default n
endif
+
+endmenu
+
+menu "Hook system"
+
+config NX_HOOK_ENABLE
+ bool "Enable hook system for nxos"
+ default n
+
+ if NX_HOOK_ENABLE
+ config NX_MAIN_THREAD_HOOK
+ bool "The hook for main thread"
+ default n
+
+ config NX_STARTUP_HOOK
+ bool "The hook for OS startup"
+ default n
+
+ config NX_CORE_STARTUP_HOOK
+ bool "The hook for each cpu core startup"
+ default n
+
+ config NX_TICKS_HOOK
+ bool "The hook for ticks"
+ default n
+
+ config NX_IDLE_HOOK
+ bool "The hook for idle task"
+ default n
+
+ config NX_CONTEXT_SWITCH_HOOK
+ bool "The hook for thread context switch"
+ default n
+
+ config NX_PREV_THREAD_HOOK
+ bool "The hook for thread enter running"
+ default n
+
+ config NX_POST_THREAD_HOOK
+ bool "The hook for thread leave running"
+ default n
+
+ config NX_SYSCALL_ENTER_HOOK
+ bool "The hook for syscall enter"
+ default n
+
+ config NX_SYSCALL_LEAVE_HOOK
+ bool "The hook for syscall leave"
+ default n
+ endif
+
endmenu
diff --git a/src/kernel/hooks.c b/src/kernel/hooks.c
new file mode 100644
index 0000000000000000000000000000000000000000..1090569ba7cd389799da6578f86b872ed6260d47
--- /dev/null
+++ b/src/kernel/hooks.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2018-2022, NXOS Development Team
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Contains: Hook system
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2022-10-10 JasonHu Init
+ */
+
+#include
+
+#ifdef NX_MAIN_THREAD_HOOK
+NX_WEAK_SYM void NX_MainThreadHook(void) {}
+#endif
+
+#ifdef NX_STARTUP_HOOK
+NX_WEAK_SYM void NX_StartupHook(void) {}
+#endif
+
+#ifdef NX_CORE_STARTUP_HOOK
+NX_WEAK_SYM void NX_CoreStartupHook(NX_UArch coreId) {}
+#endif
+
+#ifdef NX_TICKS_HOOK
+NX_WEAK_SYM void NX_TicksHook(void) {}
+#endif
+
+#ifdef NX_IDLE_HOOK
+NX_WEAK_SYM void NX_IdleHook(void) {}
+#endif
+
+#ifdef NX_CONTEXT_SWITCH_HOOK
+NX_WEAK_SYM void NX_ContextSwitchHook(NX_Thread * prev, NX_Thread * next) {}
+#endif
+
+#ifdef NX_PREV_THREAD_HOOK
+NX_WEAK_SYM void NX_PrevThreadHook(NX_Thread * thread) {}
+#endif
+
+#ifdef NX_POST_THREAD_HOOK
+NX_WEAK_SYM void NX_PostThreadHook(NX_Thread * thread) {}
+#endif
+
+#ifdef NX_SYSCALL_ENTER_HOOK
+NX_WEAK_SYM void NX_SyscallEnterHook(NX_SyscallApi api, NX_UArch arg0, NX_UArch arg1, NX_UArch arg2,
+ NX_UArch arg3, NX_UArch arg4, NX_UArch arg5, NX_UArch arg6) {}
+#endif
+
+#ifdef NX_SYSCALL_LEAVE_HOOK
+NX_WEAK_SYM void NX_SyscallLeaveHook(NX_SyscallApi api, NX_UArch retval) {}
+#endif
diff --git a/src/platform/d1 b/src/platform/d1
index 22e85ffd51d5bf85a2b0d4653fc0df55abbaab60..84967ac468825300e57969b602bc300f8e4bb306 160000
--- a/src/platform/d1
+++ b/src/platform/d1
@@ -1 +1 @@
-Subproject commit 22e85ffd51d5bf85a2b0d4653fc0df55abbaab60
+Subproject commit 84967ac468825300e57969b602bc300f8e4bb306
diff --git a/src/platform/hifive_unmached b/src/platform/hifive_unmached
index 79794e9d5ca4cf619739b2420939188f5ef65de6..6207cd280e9b208f684ea3254e8420acbda17a61 160000
--- a/src/platform/hifive_unmached
+++ b/src/platform/hifive_unmached
@@ -1 +1 @@
-Subproject commit 79794e9d5ca4cf619739b2420939188f5ef65de6
+Subproject commit 6207cd280e9b208f684ea3254e8420acbda17a61
diff --git a/src/platform/i386 b/src/platform/i386
index 27ffbb574d5305df433e52e698b80b600aba2710..6eb04fe7cd4c7eea858c2a0d56a17a05709b89fb 160000
--- a/src/platform/i386
+++ b/src/platform/i386
@@ -1 +1 @@
-Subproject commit 27ffbb574d5305df433e52e698b80b600aba2710
+Subproject commit 6eb04fe7cd4c7eea858c2a0d56a17a05709b89fb
diff --git a/src/platform/k210 b/src/platform/k210
index 6eac7f66940a13e9c07f3e6de6bfa8a686459557..d1b257011ef719ff9f7330aadb6adb712ce90365 160000
--- a/src/platform/k210
+++ b/src/platform/k210
@@ -1 +1 @@
-Subproject commit 6eac7f66940a13e9c07f3e6de6bfa8a686459557
+Subproject commit d1b257011ef719ff9f7330aadb6adb712ce90365
diff --git a/src/platform/qemu_riscv64 b/src/platform/qemu_riscv64
index 609c44b20598b14952a78acbcc2f9684a050dfe7..b1487829cd6fe850e151784260aa0a8c5be0c699 160000
--- a/src/platform/qemu_riscv64
+++ b/src/platform/qemu_riscv64
@@ -1 +1 @@
-Subproject commit 609c44b20598b14952a78acbcc2f9684a050dfe7
+Subproject commit b1487829cd6fe850e151784260aa0a8c5be0c699
diff --git a/src/sched/idle.c b/src/sched/idle.c
index eb44c3a54edd47d8814493ed433269be534632a8..4a5a2e2ca39ea5e3a18c32387a6654e09eb18d0b 100644
--- a/src/sched/idle.c
+++ b/src/sched/idle.c
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#define IDLE_TIME_S 1000 /* 1s */
@@ -46,6 +47,7 @@ NX_PRIVATE void IdleThreadEntry(void *arg)
NX_LOG_I("Idle thread: %s startting...", self->name);
while (1)
{
+ NX_IDLE_HOOK();
NX_ThreadYield();
}
}
diff --git a/src/sched/sched.c b/src/sched/sched.c
index f0246f827cc9d2cb619dd60da265354c443ce10d..079e01a6ae6cec43e68f75fc0ac4331c10a5b8e9 100644
--- a/src/sched/sched.c
+++ b/src/sched/sched.c
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
NX_IMPORT NX_ThreadManager gThreadManagerObject;
NX_IMPORT NX_Atomic gActivedCoreCount;
@@ -59,6 +60,7 @@ NX_INLINE void SchedToNext(NX_Thread *next)
NX_INLINE void SchedFromPrevToNext(NX_Thread *prev, NX_Thread *next)
{
+ NX_CONTEXT_SWITCH_HOOK(prev, next);
SchedSwithProcess(next);
NX_ContextSwitchPrevNext((NX_Addr)&prev->stack, (NX_Addr)&next->stack);
}
@@ -189,6 +191,9 @@ void NX_SchedExit(void)
NX_LOG_D("Thread exit: %d", cur->tid);
cur->state = NX_THREAD_EXIT;
+
+ NX_POST_THREAD_HOOK(cur);
+
NX_ThreadEnququeExitList(cur);
NX_SchedInterruptDisabled(level);
diff --git a/src/sched/smp.c b/src/sched/smp.c
index dcbfd1d7ff26c1326e2a467fc0359f2c38a01a09..cf596b507e3500d2e09004f32d2c93080e588b0e 100644
--- a/src/sched/smp.c
+++ b/src/sched/smp.c
@@ -18,6 +18,7 @@
#include
#include
+#include
NX_IMPORT NX_Error NX_HalInitClock(void);
@@ -243,6 +244,8 @@ NX_Error NX_SMP_SetRunning(NX_UArch coreId, NX_Thread *thread)
return NX_EINTR;
}
+ NX_PREV_THREAD_HOOK(thread);
+
thread->state = NX_THREAD_RUNNING;
cpu->threadRunning = thread;
NX_SpinUnlockIRQ(&cpu->lock, level);
diff --git a/src/sched/thread.c b/src/sched/thread.c
index 2b92a6643150b710413f63023e52ec9a111854e5..6b424c9756b4cb9f51b75cd236ad20d0613ff575 100644
--- a/src/sched/thread.c
+++ b/src/sched/thread.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
NX_ThreadManager gThreadManagerObject;
@@ -214,6 +215,8 @@ void NX_ThreadReadyRunLocked(NX_Thread *thread, int flags)
{
thread->state = NX_THREAD_READY;
+ NX_POST_THREAD_HOOK(thread);
+
if (thread->onCore < NX_MULTI_CORES_NR) /* add to core pending list */
{
NX_SMP_EnqueueThreadIrqDisabled(thread->onCore, thread, flags);
@@ -404,6 +407,9 @@ NX_Error NX_ThreadBlockLockedIRQ(NX_Thread *thread, NX_Spin *lock, NX_UArch irqL
if (thread->state == NX_THREAD_READY)
{ /* remove from ready list */
thread->state = NX_THREAD_BLOCKED;
+
+ NX_POST_THREAD_HOOK(thread);
+
NX_ThreadUnreadyRun(thread);
if (lock)
@@ -418,6 +424,9 @@ NX_Error NX_ThreadBlockLockedIRQ(NX_Thread *thread, NX_Spin *lock, NX_UArch irqL
else if (thread->state == NX_THREAD_RUNNING)
{ /* set as block, then sched */
thread->state = NX_THREAD_BLOCKED;
+
+ NX_POST_THREAD_HOOK(thread);
+
NX_SchedLockedIRQ(irqLevel, lock);
if (NX_ThreadCheckInterrupt(thread))
diff --git a/src/time/clock.c b/src/time/clock.c
index 0b70f8b16a138d35ee505f3d0078b0971e56b249..21a966fe4ca509b1705fca6ca978867fcbb3e97c 100644
--- a/src/time/clock.c
+++ b/src/time/clock.c
@@ -21,6 +21,7 @@
#include
#include
+#include
#define NX_LOG_NAME "Clock"
#include
@@ -45,6 +46,7 @@ void NX_ClockTickSet(NX_ClockTick tick)
void NX_ClockTickGo(void)
{
+ NX_TICKS_HOOK();
/* only boot core change system clock and timer */
if (NX_SMP_GetBootCore() == NX_SMP_GetIdx())
{