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()) {