diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index d0046359..9cda478c 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -52,6 +52,7 @@ typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE; typedef enum _MODE MODE, *PMODE; typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; +typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; /* Structures forward references */ diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 7668645d..a06a4fd1 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -43,25 +43,27 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c ${XTOSKRNL_SOURCE_DIR}/kd/globals.c - ${XTOSKRNL_SOURCE_DIR}/ke/apc.c - ${XTOSKRNL_SOURCE_DIR}/ke/dpc.c - ${XTOSKRNL_SOURCE_DIR}/ke/event.c + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc + ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/apc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc + ${XTOSKRNL_SOURCE_DIR}/ke/crash.cc + ${XTOSKRNL_SOURCE_DIR}/ke/data.cc + ${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc + ${XTOSKRNL_SOURCE_DIR}/ke/event.cc + ${XTOSKRNL_SOURCE_DIR}/ke/exports.cc ${XTOSKRNL_SOURCE_DIR}/ke/globals.c - ${XTOSKRNL_SOURCE_DIR}/ke/info.c - ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c - ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c - ${XTOSKRNL_SOURCE_DIR}/ke/kthread.c - ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.c - ${XTOSKRNL_SOURCE_DIR}/ke/panic.c - ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c - ${XTOSKRNL_SOURCE_DIR}/ke/semphore.c - ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c - ${XTOSKRNL_SOURCE_DIR}/ke/sysres.c - ${XTOSKRNL_SOURCE_DIR}/ke/timer.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.c - ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c + ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc + ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc + ${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc + ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc + ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc + ${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc + ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc + ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc + ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc ${XTOSKRNL_SOURCE_DIR}/mm/globals.c ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c ${XTOSKRNL_SOURCE_DIR}/mm/init.c diff --git a/xtoskrnl/ar/amd64/procsup.cc b/xtoskrnl/ar/amd64/procsup.cc index b4cc8868..f91e0ab3 100644 --- a/xtoskrnl/ar/amd64/procsup.cc +++ b/xtoskrnl/ar/amd64/procsup.cc @@ -306,9 +306,9 @@ ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; /* Set process and thread information */ - ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; - ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock; + ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; ProcessorBlock->Prcb.NextThread = nullptr; /* Set initial MXCSR register value */ diff --git a/xtoskrnl/ar/i686/procsup.cc b/xtoskrnl/ar/i686/procsup.cc index f88f6bfd..823cf312 100644 --- a/xtoskrnl/ar/i686/procsup.cc +++ b/xtoskrnl/ar/i686/procsup.cc @@ -303,9 +303,9 @@ ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; /* Set process and thread information */ - ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; - ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; + ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock; + ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock; ProcessorBlock->Prcb.NextThread = nullptr; /* Set initial runlevel */ diff --git a/xtoskrnl/ex/rundown.cc b/xtoskrnl/ex/rundown.cc index 2af354b6..5f9ef6d8 100644 --- a/xtoskrnl/ex/rundown.cc +++ b/xtoskrnl/ex/rundown.cc @@ -9,6 +9,7 @@ #include +/* Kernel Executive */ namespace EX { @@ -139,7 +140,7 @@ Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count)) { - KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE); + KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE); } break; diff --git a/xtoskrnl/includes/ke.hh b/xtoskrnl/includes/ke.hh new file mode 100644 index 00000000..063a367a --- /dev/null +++ b/xtoskrnl/includes/ke.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke.hh + * DESCRIPTION: Kernel Library + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_HH +#define __XTOSKRNL_KE_HH + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* __XTOSKRNL_KE_HH */ diff --git a/xtoskrnl/includes/ke/apc.hh b/xtoskrnl/includes/ke/apc.hh new file mode 100644 index 00000000..fc6c0cc0 --- /dev/null +++ b/xtoskrnl/includes/ke/apc.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/apc.hh + * DESCRIPTION: Kernel APC objects support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_APC_HH +#define __XTOSKRNL_KE_APC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Apc + { + public: + STATIC XTAPI VOID InitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context); + }; +} + +#endif /* __XTOSKRNL_KE_APC_HH */ diff --git a/xtoskrnl/includes/ke/bootinfo.hh b/xtoskrnl/includes/ke/bootinfo.hh new file mode 100644 index 00000000..d7276581 --- /dev/null +++ b/xtoskrnl/includes/ke/bootinfo.hh @@ -0,0 +1,38 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/bootinfo.hh + * DESCRIPTION: Bootloader-provided system information handling support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_BOOTINFO_HH +#define __XTOSKRNL_KE_BOOTINFO_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class BootInformation + { + private: + STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock; + + public: + STATIC XTAPI PVOID GetDebugPrint(VOID); + STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID); + STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter); + STATIC XTAPI PLIST_ENTRY GetSystemResources(VOID); + STATIC XTAPI VOID SetInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block); + + STATIC XTAPI PKERNEL_INITIALIZATION_BLOCK GetInitializationBlock(VOID) + { + return InitializationBlock; + } + }; +} + +#endif /* __XTOSKRNL_KE_BOOTINFO_HH */ diff --git a/xtoskrnl/includes/ke/crash.hh b/xtoskrnl/includes/ke/crash.hh new file mode 100644 index 00000000..88356ad8 --- /dev/null +++ b/xtoskrnl/includes/ke/crash.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/crash.hh + * DESCRIPTION: System shutdown and kernel panic mechanism + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_CRASH_HH +#define __XTOSKRNL_KE_CRASH_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Crash + { + public: + STATIC XTAPI VOID HaltSystem(VOID); + STATIC XTAPI VOID Panic(IN ULONG Code); + STATIC XTAPI VOID PanicEx(IN ULONG Code, + IN ULONG_PTR Parameter1, + IN ULONG_PTR Parameter2, + IN ULONG_PTR Parameter3, + IN ULONG_PTR Parameter4); + }; +} + +#endif /* __XTOSKRNL_KE_CRASH_HH */ diff --git a/xtoskrnl/includes/ke/dpc.hh b/xtoskrnl/includes/ke/dpc.hh new file mode 100644 index 00000000..e3266b62 --- /dev/null +++ b/xtoskrnl/includes/ke/dpc.hh @@ -0,0 +1,37 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/dpc.hh + * DESCRIPTION: Deferred Procedure Call (DPC) support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_DPC_HH +#define __XTOSKRNL_KE_DPC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Dpc + { + public: + STATIC XTAPI VOID InitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext); + STATIC XTAPI VOID InitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext); + STATIC XTAPI VOID SetTargetProcessor(IN PKDPC Dpc, + IN CCHAR Number); + STATIC XTAPI VOID SignalCallDone(IN PVOID SystemArgument); + STATIC XTAPI BOOLEAN SignalCallSynchronize(IN PVOID SystemArgument); + + private: + STATIC XTFASTCALL VOID RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb); + }; +} + +#endif /* __XTOSKRNL_KE_DPC_HH */ diff --git a/xtoskrnl/includes/ke/event.hh b/xtoskrnl/includes/ke/event.hh new file mode 100644 index 00000000..74cdd4cb --- /dev/null +++ b/xtoskrnl/includes/ke/event.hh @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/event.hh + * DESCRIPTION: Kernel events support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_EVENT_HH +#define __XTOSKRNL_KE_EVENT_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Event + { + public: + STATIC XTAPI VOID ClearEvent(IN PKEVENT Event); + STATIC XTAPI VOID InitializeEvent(OUT PKEVENT Event, + IN KEVENT_TYPE EventType, + IN BOOLEAN InitialState); + STATIC XTAPI LONG SetEvent(IN PKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait); + }; +} + +#endif /* __XTOSKRNL_KE_EVENT_HH */ diff --git a/xtoskrnl/includes/ke/info.hh b/xtoskrnl/includes/ke/info.hh new file mode 100644 index 00000000..4ff789e6 --- /dev/null +++ b/xtoskrnl/includes/ke/info.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/info.hh + * DESCRIPTION: Generic kernel information support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_INFO_HH +#define __XTOSKRNL_KE_INFO_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Info + { + public: + STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID); + STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter); + }; +} + +#endif /* __XTOSKRNL_KE_INFO_HH */ diff --git a/xtoskrnl/includes/ke/irq.hh b/xtoskrnl/includes/ke/irq.hh new file mode 100644 index 00000000..8817fe29 --- /dev/null +++ b/xtoskrnl/includes/ke/irq.hh @@ -0,0 +1,26 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/irq.hh + * DESCRIPTION: Kernel interrupts support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_IRQ_HH +#define __XTOSKRNL_KE_IRQ_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Irq + { + public: + STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector, + IN PVOID Handler); + }; +} + +#endif /* __XTOSKRNL_KE_IRQ_HH */ diff --git a/xtoskrnl/includes/ke/kprocess.hh b/xtoskrnl/includes/ke/kprocess.hh new file mode 100644 index 00000000..ae7c370b --- /dev/null +++ b/xtoskrnl/includes/ke/kprocess.hh @@ -0,0 +1,33 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kprocess.hh + * DESCRIPTION: XT kernel process manipulation support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KPROCESS_HH +#define __XTOSKRNL_KE_KPROCESS_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KProcess + { + private: + STATIC EPROCESS InitialProcess; + + public: + STATIC XTAPI PEPROCESS GetInitialProcess(VOID); + STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process, + IN KPRIORITY Priority, + IN KAFFINITY Affinity, + IN PULONG_PTR DirectoryTable, + IN BOOLEAN Alignment); + }; +} + +#endif /* __XTOSKRNL_KE_KPROCESS_HH */ diff --git a/xtoskrnl/includes/ke/krnlinit.hh b/xtoskrnl/includes/ke/krnlinit.hh new file mode 100644 index 00000000..e92cceef --- /dev/null +++ b/xtoskrnl/includes/ke/krnlinit.hh @@ -0,0 +1,30 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/krnlinit.hh + * DESCRIPTION: XTOS Kernel initialization + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KRNLINIT_HH +#define __XTOSKRNL_KE_KRNLINIT_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KernelInit + { + public: + STATIC XTAPI VOID InitializeMachine(VOID); + STATIC XTAPI VOID SwitchBootStack(VOID); + + private: + STATIC XTAPI VOID InitializeKernel(VOID); + STATIC XTAPI VOID StartKernel(VOID); + }; +} + +#endif /* __XTOSKRNL_KE_KRNLINIT_HH */ diff --git a/xtoskrnl/includes/ke/kthread.hh b/xtoskrnl/includes/ke/kthread.hh new file mode 100644 index 00000000..f924e71d --- /dev/null +++ b/xtoskrnl/includes/ke/kthread.hh @@ -0,0 +1,55 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kthread.hh + * DESCRIPTION: XT kernel thread manipulation support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KTHREAD_HH +#define __XTOSKRNL_KE_KTHREAD_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KThread + { + private: + STATIC ETHREAD InitialThread; + + public: + STATIC XTFASTCALL VOID ExitDispatcher(IN KRUNLEVEL OldRunLevel); + STATIC XTAPI PETHREAD GetInitialThread(VOID); + STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID EnvironmentBlock, + IN PVOID Stack, + IN BOOLEAN StartThread); + STATIC XTAPI VOID StartThread(IN PKTHREAD Thread); + + private: + STATIC XTAPI VOID InitializeThreadContext(IN PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT ContextRecord); + STATIC XTAPI VOID SuspendNop(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE *NormalRoutine, + IN OUT PVOID *NormalContext, + IN OUT PVOID *SystemArgument1, + IN OUT PVOID *SystemArgument2); + STATIC XTAPI VOID SuspendRundown(IN PKAPC Apc); + STATIC XTAPI VOID SuspendThread(IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + }; +} + +#endif /* __XTOSKRNL_KE_KTHREAD_HH */ diff --git a/xtoskrnl/includes/ke/kubsan.hh b/xtoskrnl/includes/ke/kubsan.hh new file mode 100644 index 00000000..34bd2a87 --- /dev/null +++ b/xtoskrnl/includes/ke/kubsan.hh @@ -0,0 +1,67 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/kubsan.hh + * DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_KUBSAN_HH +#define __XTOSKRNL_KE_KUBSAN_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class KUbsan + { + private: + STATIC BOOLEAN ActiveFrame; + + public: + STATIC XTCDECL VOID HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, + PVOID Lhs, + PVOID Rhs); + STATIC XTCDECL VOID HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data); + STATIC XTCDECL VOID HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR OldValue); + STATIC XTCDECL VOID HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data); + STATIC XTCDECL VOID HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + STATIC XTCDECL VOID HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Index); + STATIC XTCDECL VOID HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs); + STATIC XTCDECL VOID HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer); + + private: + STATIC XTCDECL BOOLEAN CheckReport(PKUBSAN_SOURCE_LOCATION Location); + STATIC XTCDECL VOID EnterFrame(PKUBSAN_SOURCE_LOCATION Location, + PCCHAR Reason); + STATIC XTCDECL LONGLONG GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value); + STATIC XTCDECL PCCHAR GetTypeKind(UCHAR TypeCheckKind); + STATIC XTCDECL ULONGLONG GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value); + STATIC XTCDECL VOID LeaveFrame(); + }; +} + +#endif /* __XTOSKRNL_KE_KUBSAN_HH */ diff --git a/xtoskrnl/includes/ke/proc.hh b/xtoskrnl/includes/ke/proc.hh new file mode 100644 index 00000000..08ee47ab --- /dev/null +++ b/xtoskrnl/includes/ke/proc.hh @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/proc.hh + * DESCRIPTION: Processor-related functionality for the kernel + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_PROC_HH +#define __XTOSKRNL_KE_PROC_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Processor + { + public: + STATIC XTAPI PKPROCESSOR_BLOCK GetCurrentProcessorBlock(VOID); + STATIC XTAPI PKPROCESSOR_CONTROL_BLOCK GetCurrentProcessorControlBlock(VOID); + STATIC XTAPI ULONG GetCurrentProcessorNumber(VOID); + STATIC XTAPI PKTHREAD GetCurrentThread(VOID); + STATIC XTAPI VOID SaveProcessorState(OUT PKPROCESSOR_STATE CpuState); + }; +} + +#endif /* __XTOSKRNL_KE_PROC_HH */ diff --git a/xtoskrnl/includes/ke/runlevel.hh b/xtoskrnl/includes/ke/runlevel.hh new file mode 100644 index 00000000..d3fca059 --- /dev/null +++ b/xtoskrnl/includes/ke/runlevel.hh @@ -0,0 +1,27 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/runlevel.hh + * DESCRIPTION: Running Level management support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_RUNLEVEL_HH +#define __XTOSKRNL_KE_RUNLEVEL_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class RunLevel + { + public: + STATIC XTFASTCALL KRUNLEVEL GetCurrentRunLevel(VOID); + STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel); + STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel); + }; +} + +#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */ diff --git a/xtoskrnl/includes/ke/semphore.hh b/xtoskrnl/includes/ke/semphore.hh new file mode 100644 index 00000000..50c7dfdf --- /dev/null +++ b/xtoskrnl/includes/ke/semphore.hh @@ -0,0 +1,32 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/semphore.hh + * DESCRIPTION: Semaphores support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SEMPHORE_HH +#define __XTOSKRNL_KE_SEMPHORE_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Semaphore + { + public: + STATIC XTAPI VOID InitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit); + STATIC XTAPI LONG ReadState(IN PKSEMAPHORE Semaphore); + STATIC XTAPI LONG ReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait); + }; +} + +#endif /* __XTOSKRNL_KE_SEMPHORE_HH */ diff --git a/xtoskrnl/includes/ke/spinlock.hh b/xtoskrnl/includes/ke/spinlock.hh new file mode 100644 index 00000000..7efcbe22 --- /dev/null +++ b/xtoskrnl/includes/ke/spinlock.hh @@ -0,0 +1,29 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/spinlock.hh + * DESCRIPTION: Spinlocks support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SPINLOCK_HH +#define __XTOSKRNL_KE_SPINLOCK_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class SpinLock + { + public: + STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); + STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); + STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock); + STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); + STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); + }; +} + +#endif /* __XTOSKRNL_KE_SPINLOCK_HH */ diff --git a/xtoskrnl/includes/ke/sysres.hh b/xtoskrnl/includes/ke/sysres.hh new file mode 100644 index 00000000..b97603de --- /dev/null +++ b/xtoskrnl/includes/ke/sysres.hh @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/sysres.hh + * DESCRIPTION: System boot resources management + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_SYSRES_HH +#define __XTOSKRNL_KE_SYSRES_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class SystemResources + { + private: + STATIC LIST_ENTRY ResourcesListHead; + STATIC KSPIN_LOCK ResourcesLock; + + public: + STATIC XTAPI XTSTATUS AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + STATIC XTAPI XTSTATUS GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + STATIC XTAPI VOID InitializeResources(VOID); + STATIC XTAPI VOID ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); + + private: + STATIC XTAPI XTSTATUS GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN ResourceLock, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); + + }; +} + +#endif /* __XTOSKRNL_KE_SYSRES_HH */ diff --git a/xtoskrnl/includes/ke/timer.hh b/xtoskrnl/includes/ke/timer.hh new file mode 100644 index 00000000..55a5b6f3 --- /dev/null +++ b/xtoskrnl/includes/ke/timer.hh @@ -0,0 +1,37 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ke/timer.hh + * DESCRIPTION: Kernel timer object support + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KE_TIMER_HH +#define __XTOSKRNL_KE_TIMER_HH + +#include + + +/* Kernel Library */ +namespace KE +{ + class Timer + { + public: + STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer); + STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer); + STATIC XTAPI BOOLEAN GetState(IN PKTIMER Timer); + STATIC XTAPI VOID InitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type); + STATIC XTAPI ULONGLONG QueryTimer(IN PKTIMER Timer); + STATIC XTAPI VOID SetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc); + + private: + STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer); + }; +} + +#endif /* __XTOSKRNL_KE_TIMER_HH */ diff --git a/xtoskrnl/ke/amd64/irqs.c b/xtoskrnl/ke/amd64/irq.cc similarity index 75% rename from xtoskrnl/ke/amd64/irqs.c rename to xtoskrnl/ke/amd64/irq.cc index 8fbf9925..a5a6a458 100644 --- a/xtoskrnl/ke/amd64/irqs.c +++ b/xtoskrnl/ke/amd64/irq.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/irqs.c + * FILE: xtoskrnl/ke/amd64/irq.cc * DESCRIPTION: Kernel interrupts support for amd64 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Sets new interrupt handler for the existing IDT entry. * @@ -24,8 +28,8 @@ */ XTAPI VOID -KeSetInterruptHandler(IN ULONG Vector, - IN PVOID Handler) +Irq::SetInterruptHandler(IN ULONG Vector, + IN PVOID Handler) { PKPROCESSOR_BLOCK ProcessorBlock; @@ -37,3 +41,16 @@ KeSetInterruptHandler(IN ULONG Vector, ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF); ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32; } + +} /* namespace */ + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +KeSetInterruptHandler(IN ULONG Vector, + IN PVOID Handler) +{ + KE::Irq::SetInterruptHandler(Vector, Handler); +} diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.cc similarity index 69% rename from xtoskrnl/ke/amd64/krnlinit.c rename to xtoskrnl/ke/amd64/krnlinit.cc index 3eb19a61..40cead0d 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/krnlinit.c + * FILE: xtoskrnl/ke/amd64/krnlinit.cc * DESCRIPTION: CPU architecture specific kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * This routine initializes XT kernel. * @@ -18,7 +22,7 @@ */ XTAPI VOID -KepInitializeKernel(VOID) +KernelInit::InitializeKernel(VOID) { XTSTATUS Status; @@ -28,7 +32,7 @@ KepInitializeKernel(VOID) { /* Hardware layer initialization failed, kernel panic */ DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); - KePanic(0); + Crash::Panic(0); } } @@ -41,7 +45,7 @@ KepInitializeKernel(VOID) */ XTAPI VOID -KepInitializeMachine(VOID) +KernelInit::InitializeMachine(VOID) { /* Re-enable IDE interrupts */ HlIoPortOutByte(0x376, 0); @@ -66,7 +70,7 @@ KepInitializeMachine(VOID) */ XTAPI VOID -KepStartKernel(VOID) +KernelInit::StartKernel(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; ULONG_PTR PageDirectory[2]; @@ -74,8 +78,8 @@ KepStartKernel(VOID) PKTHREAD CurrentThread; /* Get processor control block and current thread */ - Prcb = KeGetCurrentProcessorControlBlock(); - CurrentThread = KeGetCurrentThread(); + Prcb = Processor::GetCurrentProcessorControlBlock(); + CurrentThread = Processor::GetCurrentThread(); /* Get current process */ CurrentProcess = CurrentThread->ApcState.Process; @@ -84,23 +88,22 @@ KepStartKernel(VOID) PoInitializeProcessorControlBlock(Prcb); /* Save processor state */ - KepSaveProcessorState(&Prcb->ProcessorState); + Processor::SaveProcessorState(&Prcb->ProcessorState); /* Lower to APC runlevel */ - KeLowerRunLevel(APC_LEVEL); + RunLevel::LowerRunLevel(APC_LEVEL); /* Initialize XTOS kernel */ - KepInitializeKernel(); + InitializeKernel(); /* Initialize Idle process */ - RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; PageDirectory[1] = 0; - KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); + KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE); + KThread::InitializeThread(CurrentProcess, CurrentThread, nullptr, nullptr, nullptr, nullptr, nullptr, ArGetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -109,12 +112,12 @@ KepStartKernel(VOID) CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; /* Enter infinite loop */ - DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); - for(;;); + DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n"); + Crash::HaltSystem(); } /** - * Switches execution to a new boot stack and transfers control to the KepStartKernel() routine. + * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * * @return This routine does not return any value. * @@ -122,20 +125,28 @@ KepStartKernel(VOID) */ XTAPI VOID -KepSwitchBootStack() +KernelInit::SwitchBootStack(VOID) { - /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ - ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + ULONG_PTR Stack; + PVOID StartKernel; - /* Discard old stack frame, switch stack and jump to KepStartKernel() */ + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + + /* Get address of KernelInit::StartKernel() */ + StartKernel = (PVOID)KernelInit::StartKernel; + + /* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */ __asm__ volatile("mov %0, %%rdx\n" "xor %%rbp, %%rbp\n" "mov %%rdx, %%rsp\n" "sub %1, %%rsp\n" - "jmp KepStartKernel\n" + "jmp *%2\n" : : "m" (Stack), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), - "p" (KepStartKernel) + "r" (StartKernel) : "rdx", "rbp", "rsp", "memory"); } + +} /* namespace */ diff --git a/xtoskrnl/ke/amd64/kthread.c b/xtoskrnl/ke/amd64/kthread.cc similarity index 95% rename from xtoskrnl/ke/amd64/kthread.c rename to xtoskrnl/ke/amd64/kthread.cc index 096d7d68..06099b1d 100644 --- a/xtoskrnl/ke/amd64/kthread.c +++ b/xtoskrnl/ke/amd64/kthread.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/kthread.c + * FILE: xtoskrnl/ke/amd64/kthread.cc * DESCRIPTION: AMD64 thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Initializes CPU architecture dependent context of a thread. * @@ -33,7 +37,7 @@ */ XTAPI VOID -KepInitializeThreadContext(IN PKTHREAD Thread, +KThread::InitializeThreadContext(IN PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext, @@ -116,3 +120,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread, /* Set thread stack */ Thread->KernelStack = &ThreadFrame->SwitchFrame; } + +} /* namespace */ \ No newline at end of file diff --git a/xtoskrnl/ke/amd64/proc.c b/xtoskrnl/ke/amd64/proc.c deleted file mode 100644 index 04b7ca67..00000000 --- a/xtoskrnl/ke/amd64/proc.c +++ /dev/null @@ -1,114 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/amd64/proc.c - * DESCRIPTION: AMD64 processor-related functionality for the kernel - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Gets the processor block for the currently executing processor. - * - * @return This routine returns the current processor block read from the GS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID) -{ - /* Get processor block from GS register */ - return (PKPROCESSOR_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); -} - -/** - * Gets the processor control block for the currently executing processor. - * - * @return This routine returns the current processor control block read from the GS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID) -{ - return (PKPROCESSOR_CONTROL_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); -} - -/** - * Gets the number of the currently executing processor. - * - * @return This routine returns the zero-indexed processor number. - * - * @since XT 1.0 - */ -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); -} - -/** - * Gets the current thread running on the currently executing processor. - * - * @return This routine returns the address of the current thread object. - * - * @since NT 3.5 - */ -XTAPI -PKTHREAD -KeGetCurrentThread(VOID) -{ - return (PKTHREAD)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); -} - -/** - * Saves the current processor state. - * - * @param State - * Supplies a pointer to the processor state structure. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) -{ - /* Save CR registers */ - CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); - CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); - CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); - CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); - CpuState->SpecialRegisters.Cr8 = ArReadControlRegister(8); - - /* Save DR registers */ - CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); - CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); - CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); - CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); - CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); - CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); - - /* Save MSR registers */ - CpuState->SpecialRegisters.MsrGsBase = ArReadModelSpecificRegister(X86_MSR_GSBASE); - CpuState->SpecialRegisters.MsrGsSwap = ArReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); - CpuState->SpecialRegisters.MsrCStar = ArReadModelSpecificRegister(X86_MSR_CSTAR); - CpuState->SpecialRegisters.MsrLStar = ArReadModelSpecificRegister(X86_MSR_LSTAR); - CpuState->SpecialRegisters.MsrStar = ArReadModelSpecificRegister(X86_MSR_STAR); - CpuState->SpecialRegisters.MsrSyscallMask = ArReadModelSpecificRegister(X86_MSR_FMASK); - - /* Save XMM control/status register */ - CpuState->SpecialRegisters.MxCsr = ArReadMxCsrRegister(); - - /* Save GDT, IDT, LDT and TaskRegister */ - ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); - ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); - ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); - ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); -} diff --git a/xtoskrnl/ke/amd64/proc.cc b/xtoskrnl/ke/amd64/proc.cc new file mode 100644 index 00000000..d4d739b7 --- /dev/null +++ b/xtoskrnl/ke/amd64/proc.cc @@ -0,0 +1,162 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/amd64/proc.cc + * DESCRIPTION: AMD64 processor-related functionality for the kernel + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Kernel Library */ +namespace KE +{ + +/** + * Gets the processor block for the currently executing processor. + * + * @return This routine returns the current processor block read from the GS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_BLOCK +Processor::GetCurrentProcessorBlock(VOID) +{ + /* Get processor block from GS register */ + return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); +} + +/** + * Gets the processor control block for the currently executing processor. + * + * @return This routine returns the current processor control block read from the GS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +Processor::GetCurrentProcessorControlBlock(VOID) +{ + return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); +} + +/** + * Gets the number of the currently executing processor. + * + * @return This routine returns the zero-indexed processor number. + * + * @since XT 1.0 + */ +XTAPI +ULONG +Processor::GetCurrentProcessorNumber(VOID) +{ + return (ULONG)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); +} + +/** + * Gets the current thread running on the currently executing processor. + * + * @return This routine returns the address of the current thread object. + * + * @since NT 3.5 + */ +XTAPI +PKTHREAD +Processor::GetCurrentThread(VOID) +{ + return (PKTHREAD)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); +} + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); + CpuState->SpecialRegisters.Cr8 = AR::CpuFunc::ReadControlRegister(8); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); + + /* Save MSR registers */ + CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_GSBASE); + CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); + CpuState->SpecialRegisters.MsrCStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_CSTAR); + CpuState->SpecialRegisters.MsrLStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_LSTAR); + CpuState->SpecialRegisters.MsrStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_STAR); + CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_FMASK); + + /* Save XMM control/status register */ + CpuState->SpecialRegisters.MxCsr = AR::CpuFunc::ReadMxCsrRegister(); + + /* Save GDT, IDT, LDT and TaskRegister */ + AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); +} + +} /* namespace */ + + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKPROCESSOR_BLOCK +KeGetCurrentProcessorBlock(VOID) +{ + return KE::Processor::GetCurrentProcessorBlock(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +KeGetCurrentProcessorControlBlock(VOID) +{ + return KE::Processor::GetCurrentProcessorControlBlock(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return KE::Processor::GetCurrentProcessorNumber(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKTHREAD +KeGetCurrentThread(VOID) +{ + return KE::Processor::GetCurrentThread(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + KE::Processor::SaveProcessorState(CpuState); +} \ No newline at end of file diff --git a/xtoskrnl/ke/apc.c b/xtoskrnl/ke/apc.cc similarity index 80% rename from xtoskrnl/ke/apc.c rename to xtoskrnl/ke/apc.cc index 2d65a9b9..32fa4bde 100644 --- a/xtoskrnl/ke/apc.c +++ b/xtoskrnl/ke/apc.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/apc.c + * FILE: xtoskrnl/ke/apc.cc * DESCRIPTION: Kernel APC objects support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Initializes an APC object. * @@ -42,14 +46,14 @@ */ XTAPI VOID -KeInitializeApc(IN PKAPC Apc, - IN PKTHREAD Thread, - IN KAPC_ENVIRONMENT Environment, - IN PKKERNEL_ROUTINE KernelRoutine, - IN PKRUNDOWN_ROUTINE RundownRoutine, - IN PKNORMAL_ROUTINE NormalRoutine, - IN KPROCESSOR_MODE ApcMode, - IN PVOID Context) +Apc::InitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context) { /* Set APC type and thread */ Apc->Type = ApcObject; @@ -89,3 +93,5 @@ KeInitializeApc(IN PKAPC Apc, /* Mark APC as not inserted yet */ Apc->Inserted = FALSE; } + +} /* namespace */ diff --git a/xtoskrnl/ke/info.c b/xtoskrnl/ke/bootinfo.cc similarity index 61% rename from xtoskrnl/ke/info.c rename to xtoskrnl/ke/bootinfo.cc index 8c01ef2f..0ab1855f 100644 --- a/xtoskrnl/ke/info.c +++ b/xtoskrnl/ke/bootinfo.cc @@ -1,14 +1,25 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/info.c - * DESCRIPTION: Generic kernel information support + * FILE: xtoskrnl/ke/bootinfo.cc + * DESCRIPTION: Bootloader-provided system information handling support * DEVELOPERS: Aiken Harris */ -#include +#include +/* Kernel Library */ +namespace KE +{ + +XTAPI +PVOID +BootInformation::GetDebugPrint(VOID) +{ + return InitializationBlock->LoaderInformation.DbgPrint; +} + /** * Retrieves the system firmware type (BIOS or UEFI). * @@ -18,9 +29,9 @@ */ XTAPI SYSTEM_FIRMWARE_TYPE -KeGetFirmwareType(VOID) +BootInformation::GetFirmwareType(VOID) { - return KeInitializationBlock->FirmwareInformation.FirmwareType; + return InitializationBlock->FirmwareInformation.FirmwareType; } /** @@ -38,17 +49,14 @@ KeGetFirmwareType(VOID) */ XTAPI XTSTATUS -KeGetKernelParameter(IN PCWSTR ParameterName, - OUT PCWSTR *Parameter) +BootInformation::GetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter) { - PCWSTR KernelParameters,Match, SearchStart; + PCWSTR Match, SearchStart; SIZE_T ParameterNameLength; - /* Get the kernel parameters */ - KernelParameters = KeInitializationBlock->KernelParameters; - /* Validate input parameters */ - if(!KernelParameters || !ParameterName || !Parameter) + if(!ParameterName || !Parameter) { /* Invalid input parameters, return error */ return STATUS_INVALID_PARAMETER; @@ -63,16 +71,16 @@ KeGetKernelParameter(IN PCWSTR ParameterName, } /* Assume the requested parameter is not present in the kernel parameters */ - *Parameter = NULL; + *Parameter = nullptr; /* Start searching from the beginning of the list */ - SearchStart = KernelParameters; + SearchStart = InitializationBlock->KernelParameters; /* Search for the parameter name */ while((Match = RtlFindWideStringInsensitive(SearchStart, ParameterName))) { /* Check if the match is at the start of the string or preceded by a space */ - if(Match == KernelParameters || *(Match - 1) == L' ') + if(Match == InitializationBlock->KernelParameters || *(Match - 1) == L' ') { /* Check the character after the match to avoid matching prefixes */ if(Match[ParameterNameLength] == L'\0' || @@ -92,3 +100,50 @@ KeGetKernelParameter(IN PCWSTR ParameterName, /* Parameter not found */ return STATUS_NOT_FOUND; } + +/** + * + * + * + * + */ +XTAPI +PLIST_ENTRY +BootInformation::GetSystemResources(VOID) +{ + return &InitializationBlock->SystemResourcesListHead; +} + +/** + * + * + * + * + */ +XTAPI +VOID +BootInformation::SetInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block) +{ + InitializationBlock = Block; +} + +} /* namespace */ + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +XTSTATUS +KeGetKernelParameter(IN PCWSTR ParameterName, + OUT PCWSTR *Parameter) +{ + return KE::BootInformation::GetKernelParameter(ParameterName, Parameter); +} + +XTCLINK +XTAPI +PKERNEL_INITIALIZATION_BLOCK +KeGetInitializationBlock(VOID) +{ + return KE::BootInformation::GetInitializationBlock(); +} \ No newline at end of file diff --git a/xtoskrnl/ke/panic.c b/xtoskrnl/ke/crash.cc similarity index 67% rename from xtoskrnl/ke/panic.c rename to xtoskrnl/ke/crash.cc index aa27ca3f..063eb88f 100644 --- a/xtoskrnl/ke/panic.c +++ b/xtoskrnl/ke/crash.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/panic.c + * FILE: xtoskrnl/ke/panic.cc * DESCRIPTION: System shutdown and kernel panic mechanism * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Halts the system. * @@ -18,14 +22,14 @@ */ XTAPI VOID -KeHaltSystem(VOID) +Crash::HaltSystem(VOID) { /* Enter infinite loop */ for(;;) { /* Halt system */ - ArClearInterruptFlag(); - ArHalt(); + AR::CpuFunc::ClearInterruptFlag(); + AR::CpuFunc::Halt(); } } @@ -41,9 +45,9 @@ KeHaltSystem(VOID) */ XTAPI VOID -KePanic(IN ULONG Code) +Crash::Panic(IN ULONG Code) { - KePanicEx(Code, 0, 0, 0, 0); + PanicEx(Code, 0, 0, 0, 0); } /** @@ -70,12 +74,33 @@ KePanic(IN ULONG Code) */ XTAPI VOID -KePanicEx(IN ULONG Code, - IN ULONG_PTR Parameter1, - IN ULONG_PTR Parameter2, - IN ULONG_PTR Parameter3, - IN ULONG_PTR Parameter4) +Crash::PanicEx(IN ULONG Code, + IN ULONG_PTR Parameter1, + IN ULONG_PTR Parameter2, + IN ULONG_PTR Parameter3, + IN ULONG_PTR Parameter4) { KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code); - KeHaltSystem(); + HaltSystem(); +} + +} /* namespace */ + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +KeHaltSystem(VOID) +{ + KE::Crash::HaltSystem(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +KePanic(ULONG Code) +{ + KE::Crash::Panic(Code); } diff --git a/xtoskrnl/ke/data.cc b/xtoskrnl/ke/data.cc new file mode 100644 index 00000000..b29b3f23 --- /dev/null +++ b/xtoskrnl/ke/data.cc @@ -0,0 +1,34 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/data.cc + * DESCRIPTION: + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Kernel Library */ +namespace KE +{ + +/* Kernel initialization block passed by boot loader */ +PKERNEL_INITIALIZATION_BLOCK BootInformation::InitializationBlock = {}; + +/* Kernel boot resources list */ +LIST_ENTRY SystemResources::ResourcesListHead; + +/* Kernel boot resources lock */ +KSPIN_LOCK SystemResources::ResourcesLock; + +/* Kernel initial process */ +EPROCESS KProcess::InitialProcess; + +/* Kernel initial thread */ +ETHREAD KThread::InitialThread = {}; + +/* Kernel UBSAN active frame flag */ +BOOLEAN KUbsan::ActiveFrame = FALSE; + +} /* namespace */ diff --git a/xtoskrnl/ke/dpc.c b/xtoskrnl/ke/dpc.cc similarity index 82% rename from xtoskrnl/ke/dpc.c rename to xtoskrnl/ke/dpc.cc index 3b7f9aff..bda583ac 100644 --- a/xtoskrnl/ke/dpc.c +++ b/xtoskrnl/ke/dpc.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/dpc.c + * FILE: xtoskrnl/ke/dpc.cc * DESCRIPTION: Deferred Procedure Call (DPC) support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Initializes Deferred Procedure Call (DPC) object. * @@ -27,9 +31,9 @@ */ XTAPI VOID -KeInitializeDpc(IN PKDPC Dpc, - IN PKDEFERRED_ROUTINE DpcRoutine, - IN PVOID DpcContext) +Dpc::InitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) { /* Initialize DPC */ Dpc->Type = DpcObject; @@ -60,9 +64,9 @@ KeInitializeDpc(IN PKDPC Dpc, */ XTAPI VOID -KeInitializeThreadedDpc(IN PKDPC Dpc, - IN PKDEFERRED_ROUTINE DpcRoutine, - IN PVOID DpcContext) +Dpc::InitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) { /* Initialize threaded DPC */ Dpc->Type = ThreadedDpcObject; @@ -90,7 +94,7 @@ KeInitializeThreadedDpc(IN PKDPC Dpc, */ XTAPI VOID -KeSetTargetProcessorDpc(IN PKDPC Dpc, +Dpc::SetTargetProcessor(IN PKDPC Dpc, IN CCHAR Number) { Dpc->Number = MAXIMUM_PROCESSORS + Number; @@ -108,9 +112,9 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc, */ XTAPI VOID -KeSignalCallDpcDone(IN PVOID SystemArgument) +Dpc::SignalCallDone(IN PVOID SystemArgument) { - RtlAtomicDecrement32(SystemArgument); + RtlAtomicDecrement32((PLONG)SystemArgument); } /** @@ -125,7 +129,7 @@ KeSignalCallDpcDone(IN PVOID SystemArgument) */ XTAPI BOOLEAN -KeSignalCallDpcSynchronize(IN PVOID SystemArgument) +Dpc::SignalCallSynchronize(IN PVOID SystemArgument) { UNIMPLEMENTED; @@ -145,7 +149,9 @@ KeSignalCallDpcSynchronize(IN PVOID SystemArgument) */ XTFASTCALL VOID -KepRetireDpcList(IN PKPROCESSOR_CONTROL_BLOCK Prcb) +Dpc::RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb) { UNIMPLEMENTED; } + +} /* namespace */ diff --git a/xtoskrnl/ke/event.c b/xtoskrnl/ke/event.cc similarity index 78% rename from xtoskrnl/ke/event.c rename to xtoskrnl/ke/event.cc index 2cffd3eb..8943e98f 100644 --- a/xtoskrnl/ke/event.c +++ b/xtoskrnl/ke/event.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/event.c + * FILE: xtoskrnl/ke/event.cc * DESCRIPTION: Kernel events support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Clears the signal state of the event. * @@ -21,7 +25,7 @@ */ XTAPI VOID -KeClearEvent(IN PKEVENT Event) +Event::ClearEvent(IN PKEVENT Event) { /* Clear event's signal state */ Event->Header.SignalState = FALSE; @@ -45,9 +49,9 @@ KeClearEvent(IN PKEVENT Event) */ XTAPI VOID -KeInitializeEvent(OUT PKEVENT Event, - IN KEVENT_TYPE EventType, - IN BOOLEAN InitialState) +Event::InitializeEvent(OUT PKEVENT Event, + IN KEVENT_TYPE EventType, + IN BOOLEAN InitialState) { /* Initialize event dispatcher header */ Event->Header.Type = EventType; @@ -75,11 +79,13 @@ KeInitializeEvent(OUT PKEVENT Event, */ XTAPI LONG -KeSetEvent(IN PKEVENT Event, - IN KPRIORITY Increment, - IN BOOLEAN Wait) +Event::SetEvent(IN PKEVENT Event, + IN KPRIORITY Increment, + IN BOOLEAN Wait) { UNIMPLEMENTED; return 0; } + +} /* namespace */ diff --git a/xtoskrnl/ke/exports.cc b/xtoskrnl/ke/exports.cc new file mode 100644 index 00000000..9040a2d0 --- /dev/null +++ b/xtoskrnl/ke/exports.cc @@ -0,0 +1,482 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/exports.cc + * DESCRIPTION: C-compatible API wrappers for exported kernel functions + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Acquires a specified queued spinlock. + * + * @param LockLevel + * Supplies the queued spinlock level. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +{ + KE::SpinLock::AcquireQueuedSpinLock(LockLevel); +} + +/** + * Acquires a kernel spin lock. + * + * @param SpinLock + * Supplies a pointer to the kernel spin lock. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::AcquireSpinLock(SpinLock); +} + +/** + * Looks for an unacquired system resource of the specified type and acquires it. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +XTSTATUS +KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + return KE::SystemResources::AcquireResource(ResourceType, ResourceHeader); +} + +/** + * Cancels the timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +BOOLEAN +KeCancelTimer(IN PKTIMER Timer) +{ + return KE::Timer::CancelTimer(Timer); +} + +/** + * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +XTSTATUS +KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + return KE::SystemResources::GetResource(ResourceType, ResourceHeader); +} + +/** + * Reads the current signal state of the given timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @return This routine returns TRUE if the timer is set, or FALSE otherwise. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +BOOLEAN +KeGetTimerState(IN PKTIMER Timer) +{ + return KE::Timer::GetState(Timer); +} + +/** + * Initializes an APC object. + * + * @param Apc + * Supplies a pointer to the APC object. + * + * @param Thread + * Supplies a pointer to the thread object. + * + * @param Environment + * Specifies an environment in which the APC will run. + * + * @param KernelRoutine + * Supplies a pointer to routine called at APC_LEVEL. + * + * @param RundownRoutine + * Supplies a pointer to routine called on thread exit. + * + * @param NormalRoutine + * Supplies a pointer to routine called at IRQL 0. + * + * @param ApcMode + * Specifies processor mode, in which NormalRoutine gets called. + * + * @param Context + * Supplies a pointer to memory area containing data passed to NormalRoutine. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeApc(IN PKAPC Apc, + IN PKTHREAD Thread, + IN KAPC_ENVIRONMENT Environment, + IN PKKERNEL_ROUTINE KernelRoutine, + IN PKRUNDOWN_ROUTINE RundownRoutine, + IN PKNORMAL_ROUTINE NormalRoutine, + IN KPROCESSOR_MODE ApcMode, + IN PVOID Context) +{ + KE::Apc::InitializeApc(Apc, Thread, Environment, KernelRoutine, RundownRoutine, NormalRoutine, ApcMode, Context); + +} + +/** + * Initializes Deferred Procedure Call (DPC) object. + * + * @param Dpc + * Supplies a pointer to the DPC being initialized. + * + * @param DpcRoutine + * Supplies a pointer to the DPC routine being called on object removal. + * + * @param DpcContext + * Supplies a pointer to memory area containing context data for DPC routine. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) +{ + KE::Dpc::InitializeDpc(Dpc, DpcRoutine, DpcContext); + +} + +/** + * Initializes Deferred Procedure Call (DPC) object. + * + * @param Dpc + * Supplies a pointer to the DPC being initialized. + * + * @param DpcRoutine + * Supplies a pointer to the DPC routine being called on object removal. + * + * @param DpcContext + * Supplies a pointer to memory area containing context data for DPC routine. + * + * @return This routine does not return any value. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +VOID +KeInitializeThreadedDpc(IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DpcRoutine, + IN PVOID DpcContext) +{ + KE::Dpc::InitializeThreadedDpc(Dpc, DpcRoutine, DpcContext); +} + +/** + * Initializes an extended kernel timer. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @param Type + * Supplies the type of the timer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeInitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type) +{ + KE::Timer::InitializeTimer(Timer, Type); +} + +/** + * Initializes a kernel semaphore object. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @param Count + * Specifies the initial count value of the semaphore. + * + * @param Limit + * Specifies a maximum count value of the semaphore. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit) +{ + KE::Semaphore::InitializeSemaphore(Semaphore, Count, Limit); +} + +/** + * Initializes a kernel spinlock object. + * + * @param SpinLock + * Supplies a pointer to a kernel spin lock. + * + * @return This routine does not return any value. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +VOID +KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::InitializeSpinLock(SpinLock); +} + +/** + * Reads semaphore's current signal state. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @return This routine returns the current signal state of the semaphore. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +LONG +KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) +{ + return KE::Semaphore::ReadState(Semaphore); +} + +/** + * Releases a queued spinlock. + * + * @param LockLevel + * Supplies the queued spinlock level. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +{ + KE::SpinLock::ReleaseQueuedSpinLock(LockLevel); +} + +/** + * Releases a semaphore. + * + * @param Semaphore + * Supplies a pointer to a semaphore object. + * + * @param Increment + * Specifies the priority increment value of the semaphore. + * + * @param Adjustment + * Specifies adjustment value added to the semaphore's initial count value. + * + * @param Wait + * Determines whether release of the semaphore will be followed by a kernel wait routine call or not. + * + * @return This routine returns a previous signal state of the semaphore. + * + * @since NT 3.5 + */ +XTCLINK +XTAPI +LONG +KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait) +{ + return KE::Semaphore::ReleaseSemaphore(Semaphore, Increment, Adjustment, Wait); +} + +/** + * Releases a kernel spin lock. + * + * @param SpinLock + * Supplies a pointer to the kernel spin lock. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTFASTCALL +VOID +KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) +{ + KE::SpinLock::ReleaseSpinLock(SpinLock); +} + +/** + * Releases system resource. + * + * @param ResourceHeader + * Specifies a pointer to the system resource header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) +{ + KE::SystemResources::ReleaseResource(ResourceHeader); +} + +/** + * Sets the target processor number for DPC. + * + * @param Dpc + * Supplies a pointer to the DPC object. + * + * @param Number + * Supplies the target processor number. + * + * @return This routine does not return any value. + * + * @since NT 4.0 + */ +XTCLINK +XTAPI +VOID +KeSetTargetProcessorDpc(IN PKDPC Dpc, + IN CCHAR Number) +{ + KE::Dpc::SetTargetProcessor(Dpc, Number); +} + +/** + * Sets the supplied timer to expire at the specified time. + * + * @param Timer + * Supplies a pointer to a timer object. + * + * @param DueTime + * Supplies the time at which the timer should expire (both absolute and relative times are supported). + * + * @param Period + * Supplies the timer period. + * + * @param Dpc + * Supplies a pointer to a Deferred Procedure Call (DPC) object. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTAPI +VOID +KeSetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc) +{ + KE::Timer::SetTimer(Timer, DueTime, Period, Dpc); +} + +/** + * Decrements the DPC call barier. + * + * @param SystemArgument + * Supplies an address of the DPC call barrier. + * + * @return This routine does not return any value. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +VOID +KeSignalCallDpcDone(IN PVOID SystemArgument) +{ + KE::Dpc::SignalCallDone(SystemArgument); +} + +/** + * Decrements the DPC call reverse barier. + * + * @param SystemArgument + * Supplies an address of the DPC call barrier. + * + * @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more. + * + * @since NT 5.2 + */ +XTCLINK +XTAPI +BOOLEAN +KeSignalCallDpcSynchronize(IN PVOID SystemArgument) +{ + return KE::Dpc::SignalCallSynchronize(SystemArgument); +} diff --git a/xtoskrnl/ke/globals.c b/xtoskrnl/ke/globals.c deleted file mode 100644 index db003012..00000000 --- a/xtoskrnl/ke/globals.c +++ /dev/null @@ -1,37 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/globals.c - * DESCRIPTION: Architecture independent global variables related to KE subsystem - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/* Pointer to boot loader provided DbgPrint() routine */ -VOID (*KeDbgPrint)(IN PCWSTR Format, IN ...) = NULL; - -/* Kernel initialization block passed by boot loader */ -PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock; - -/* Kernel initial process */ -EPROCESS KeInitialProcess; - -/* Kernel initial thread */ -ETHREAD KeInitialThread; - -/* Kernel service descriptor table */ -KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT]; - -/* Kernel process list */ -LIST_ENTRY KepProcessListHead; - -/* Kernel system resources list */ -LIST_ENTRY KepSystemResourcesListHead; - -/* Kernel system resources lock */ -KSPIN_LOCK KepSystemResourcesLock; - -/* Kernel UBSAN active frame flag */ -BOOLEAN KepUbsanActiveFrame = FALSE; diff --git a/xtoskrnl/ke/i686/irqs.c b/xtoskrnl/ke/i686/irq.cc similarity index 74% rename from xtoskrnl/ke/i686/irqs.c rename to xtoskrnl/ke/i686/irq.cc index 20aa2142..49d34ee2 100644 --- a/xtoskrnl/ke/i686/irqs.c +++ b/xtoskrnl/ke/i686/irq.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/irqs.c + * FILE: xtoskrnl/ke/i686/irq.cc * DESCRIPTION: Kernel interrupts support for i686 architecture * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Sets new interrupt handler for the existing IDT entry. * @@ -24,7 +28,7 @@ */ XTAPI VOID -KeSetInterruptHandler(IN ULONG Vector, +Irq::SetInterruptHandler(IN ULONG Vector, IN PVOID Handler) { PKPROCESSOR_BLOCK ProcessorBlock; @@ -36,3 +40,17 @@ KeSetInterruptHandler(IN ULONG Vector, ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16); } + +} /* namespace */ + + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +KeSetInterruptHandler(IN ULONG Vector, + IN PVOID Handler) +{ + KE::Irq::SetInterruptHandler(Vector, Handler); +} diff --git a/xtoskrnl/ke/i686/krnlinit.c b/xtoskrnl/ke/i686/krnlinit.cc similarity index 71% rename from xtoskrnl/ke/i686/krnlinit.c rename to xtoskrnl/ke/i686/krnlinit.cc index 51d7f119..7f37d7d8 100644 --- a/xtoskrnl/ke/i686/krnlinit.c +++ b/xtoskrnl/ke/i686/krnlinit.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/krnlinit.c + * FILE: xtoskrnl/ke/i686/krnlinit.cc * DESCRIPTION: CPU architecture specific kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * This routine initializes XT kernel. * @@ -18,7 +22,7 @@ */ XTAPI VOID -KepInitializeKernel(VOID) +KernelInit::InitializeKernel(VOID) { XTSTATUS Status; @@ -28,7 +32,7 @@ KepInitializeKernel(VOID) { /* Hardware layer initialization failed, kernel panic */ DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); - KePanic(0); + Crash::Panic(0); } } @@ -41,7 +45,7 @@ KepInitializeKernel(VOID) */ XTAPI VOID -KepInitializeMachine(VOID) +KernelInit::InitializeMachine(VOID) { /* Re-enable IDE interrupts */ HlIoPortOutByte(0x376, 0); @@ -66,7 +70,7 @@ KepInitializeMachine(VOID) */ XTAPI VOID -KepStartKernel(VOID) +KernelInit::StartKernel(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; ULONG_PTR PageDirectory[2]; @@ -74,8 +78,8 @@ KepStartKernel(VOID) PKTHREAD CurrentThread; /* Get processor control block and current thread */ - Prcb = KeGetCurrentProcessorControlBlock(); - CurrentThread = KeGetCurrentThread(); + Prcb = Processor::GetCurrentProcessorControlBlock(); + CurrentThread = Processor::GetCurrentThread(); /* Get current process */ CurrentProcess = CurrentThread->ApcState.Process; @@ -84,23 +88,22 @@ KepStartKernel(VOID) PoInitializeProcessorControlBlock(Prcb); /* Save processor state */ - KepSaveProcessorState(&Prcb->ProcessorState); + Processor::SaveProcessorState(&Prcb->ProcessorState); /* Lower to APC runlevel */ - KeLowerRunLevel(APC_LEVEL); + RunLevel::LowerRunLevel(APC_LEVEL); /* Initialize XTOS kernel */ - KepInitializeKernel(); + InitializeKernel(); /* Initialize Idle process */ - RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; PageDirectory[1] = 0; - KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); + KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE); + KThread::InitializeThread(CurrentProcess, CurrentThread, nullptr, nullptr, nullptr, nullptr, nullptr, ArGetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -109,12 +112,12 @@ KepStartKernel(VOID) CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; /* Enter infinite loop */ - DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); - for(;;); + DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n"); + Crash::HaltSystem(); } /** - * Switches execution to a new boot stack and transfers control to the specified routine. + * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * * @return This routine does not return any value. * @@ -122,22 +125,30 @@ KepStartKernel(VOID) */ XTAPI VOID -KepSwitchBootStack() +KernelInit::SwitchBootStack(VOID) { - /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ - ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + ULONG_PTR Stack; + PVOID StartKernel; - /* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */ + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + + /* Get address of KernelInit::StartKernel() */ + StartKernel = (PVOID)KernelInit::StartKernel; + + /* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */ __asm__ volatile("mov %0, %%edx\n" "xor %%ebp, %%ebp\n" "mov %%edx, %%esp\n" "sub %1, %%esp\n" "push %2\n" - "jmp _KepStartKernel@0\n" + "jmp *%3\n" : : "m" (Stack), "i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (CR0_EM | CR0_MP | CR0_TS), - "p" (KepStartKernel) + "r" (StartKernel) : "edx", "ebp", "esp", "memory"); } + +} /* namespace */ diff --git a/xtoskrnl/ke/i686/kthread.c b/xtoskrnl/ke/i686/kthread.cc similarity index 87% rename from xtoskrnl/ke/i686/kthread.c rename to xtoskrnl/ke/i686/kthread.cc index 441911a7..d1756264 100644 --- a/xtoskrnl/ke/i686/kthread.c +++ b/xtoskrnl/ke/i686/kthread.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/kthread.c + * FILE: xtoskrnl/ke/i686/kthread.cc * DESCRIPTION: I686 thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Initializes CPU architecture dependent context of a thread. * @@ -33,17 +37,17 @@ */ XTAPI VOID -KepInitializeThreadContext(IN PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT ContextRecord) +KThread::InitializeThreadContext(IN PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT ContextRecord) { PKTHREAD_INIT_FRAME ThreadFrame; PFX_SAVE_FORMAT FxSaveFormat; /* Set initial thread frame */ - ThreadFrame = (PKTHREAD_INIT_FRAME)(Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME)); + ThreadFrame = (PKTHREAD_INIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME)); /* Fill floating point save area with zeroes */ RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA)); @@ -114,3 +118,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread, /* Set thread stack */ Thread->KernelStack = &ThreadFrame->SwitchFrame; } + +} /* namespace */ diff --git a/xtoskrnl/ke/i686/proc.c b/xtoskrnl/ke/i686/proc.c deleted file mode 100644 index e7bcf213..00000000 --- a/xtoskrnl/ke/i686/proc.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/i686/proc.c - * DESCRIPTION: I686 processor-related functionality for the kernel - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * Gets the processor block for the currently executing processor. - * - * @return This routine returns the current processor block read from the FS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_BLOCK -KeGetCurrentProcessorBlock(VOID) -{ - /* Get processor block from FS register */ - return (PKPROCESSOR_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); -} - -/** - * Gets the processor control block for the currently executing processor. - * - * @return This routine returns the current processor control block read from the FS register. - * - * @since XT 1.0 - */ -XTAPI -PKPROCESSOR_CONTROL_BLOCK -KeGetCurrentProcessorControlBlock(VOID) -{ - return (PKPROCESSOR_CONTROL_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); -} - -/** - * Gets the number of the currently executing processor. - * - * @return This routine returns the zero-indexed processor number. - * - * @since XT 1.0 - */ -XTAPI -ULONG -KeGetCurrentProcessorNumber(VOID) -{ - return (ULONG)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); -} - -/** - * Gets the current thread running on the currently executing processor. - * - * @return This routine returns the address of the current thread object. - * - * @since NT 3.5 - */ -XTAPI -PKTHREAD -KeGetCurrentThread(VOID) -{ - return (PKTHREAD)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); -} - -/** - * Saves the current processor state. - * - * @param State - * Supplies a pointer to the processor state structure. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) -{ - /* Save CR registers */ - CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); - CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); - CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); - CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); - - /* Save DR registers */ - CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); - CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); - CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); - CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); - CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); - CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); - - /* Save GDT, IDT, LDT and TaskRegister */ - ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); - ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); - ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); - ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); -} diff --git a/xtoskrnl/ke/i686/proc.cc b/xtoskrnl/ke/i686/proc.cc new file mode 100644 index 00000000..e64273a9 --- /dev/null +++ b/xtoskrnl/ke/i686/proc.cc @@ -0,0 +1,150 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ke/i686/proc.c + * DESCRIPTION: I686 processor-related functionality for the kernel + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/* Kernel Library */ +namespace KE +{ + +/** + * Gets the processor block for the currently executing processor. + * + * @return This routine returns the current processor block read from the FS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_BLOCK +Processor::GetCurrentProcessorBlock(VOID) +{ + /* Get processor block from FS register */ + return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self)); +} + +/** + * Gets the processor control block for the currently executing processor. + * + * @return This routine returns the current processor control block read from the FS register. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +Processor::GetCurrentProcessorControlBlock(VOID) +{ + return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb)); +} + +/** + * Gets the number of the currently executing processor. + * + * @return This routine returns the zero-indexed processor number. + * + * @since XT 1.0 + */ +XTAPI +ULONG +Processor::GetCurrentProcessorNumber(VOID) +{ + return (ULONG)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber)); +} + +/** + * Gets the current thread running on the currently executing processor. + * + * @return This routine returns the address of the current thread object. + * + * @since NT 3.5 + */ +XTAPI +PKTHREAD +Processor::GetCurrentThread(VOID) +{ + return (PKTHREAD)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); +} + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); + + /* Save GDT, IDT, LDT and TaskRegister */ + AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); +} + +} /* namespace */ + + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKPROCESSOR_BLOCK +KeGetCurrentProcessorBlock(VOID) +{ + return KE::Processor::GetCurrentProcessorBlock(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKPROCESSOR_CONTROL_BLOCK +KeGetCurrentProcessorControlBlock(VOID) +{ + return KE::Processor::GetCurrentProcessorControlBlock(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +ULONG +KeGetCurrentProcessorNumber(VOID) +{ + return KE::Processor::GetCurrentProcessorNumber(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +PKTHREAD +KeGetCurrentThread(VOID) +{ + return KE::Processor::GetCurrentThread(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + KE::Processor::SaveProcessorState(CpuState); +} \ No newline at end of file diff --git a/xtoskrnl/ke/kprocess.c b/xtoskrnl/ke/kprocess.cc similarity index 75% rename from xtoskrnl/ke/kprocess.c rename to xtoskrnl/ke/kprocess.cc index 30a6d41f..7965cc8c 100644 --- a/xtoskrnl/ke/kprocess.c +++ b/xtoskrnl/ke/kprocess.cc @@ -1,14 +1,25 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kprocess.c + * FILE: xtoskrnl/ke/kprocess.cc * DESCRIPTION: XT kernel process manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + +XTAPI +PEPROCESS +KProcess::GetInitialProcess(VOID) +{ + return &InitialProcess; +} + /** * Initializes the process. * @@ -33,11 +44,11 @@ */ XTAPI VOID -KeInitializeProcess(IN OUT PKPROCESS Process, - IN KPRIORITY Priority, - IN KAFFINITY Affinity, - IN PULONG_PTR DirectoryTable, - IN BOOLEAN Alignment) +KProcess::InitializeProcess(IN OUT PKPROCESS Process, + IN KPRIORITY Priority, + IN KAFFINITY Affinity, + IN PULONG_PTR DirectoryTable, + IN BOOLEAN Alignment) { /* Initialize process dispatcher header */ Process->Header.Type = ProcessObject; @@ -67,3 +78,19 @@ KeInitializeProcess(IN OUT PKPROCESS Process, /* Set initial process state */ Process->State = ProcessInMemory; } + +} /* namespace */ + + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTAPI +VOID +KeInitializeProcess(IN OUT PKPROCESS Process, + IN KPRIORITY Priority, + IN KAFFINITY Affinity, + IN PULONG_PTR DirectoryTable, + IN BOOLEAN Alignment) +{ + KE::KProcess::InitializeProcess(Process, Priority, Affinity, DirectoryTable, Alignment); +} diff --git a/xtoskrnl/ke/krnlinit.c b/xtoskrnl/ke/krnlinit.cc similarity index 70% rename from xtoskrnl/ke/krnlinit.c rename to xtoskrnl/ke/krnlinit.cc index b96a5e31..436739e1 100644 --- a/xtoskrnl/ke/krnlinit.c +++ b/xtoskrnl/ke/krnlinit.cc @@ -1,14 +1,17 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/krnlinit.c + * FILE: xtoskrnl/ke/krnlinit.cc * DESCRIPTION: XT kernel initialization * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Use routines from Kernel Library */ +using namespace KE; + /** * This routine starts up the XT kernel. It is called by boot loader. * @@ -23,31 +26,31 @@ XTAPI VOID KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) { - /* Save the kernel initialization block */ - KeInitializationBlock = Parameters; - /* Verify kernel and boot loader compatibility */ - if(KeInitializationBlock->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) || - KeInitializationBlock->BlockVersion != INITIALIZATION_BLOCK_VERSION || - KeInitializationBlock->ProtocolVersion != BOOT_PROTOCOL_VERSION) + if(Parameters->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) || + Parameters->BlockVersion != INITIALIZATION_BLOCK_VERSION || + Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION) { /* Kernel and boot loader version mismatch */ - KeHaltSystem(); + Crash::HaltSystem(); } + /* Save the kernel initialization block */ + BootInformation::SetInitializationBlock(Parameters); + /* Check if debugging enabled and if boot loader provided routine for debug printing */ - if(DEBUG && KeInitializationBlock->LoaderInformation.DbgPrint) + if(DEBUG && BootInformation::GetDebugPrint()) { /* Use loader's provided DbgPrint() routine for early printing to serial console */ - KdSetPrintRoutine(KeInitializationBlock->LoaderInformation.DbgPrint); + KdSetPrintRoutine(BootInformation::GetDebugPrint()); DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME); } /* Initialize boot CPU */ - ArInitializeProcessor(NULL); + AR::ProcSup::InitializeProcessor(NULL); /* Initialize system resources */ - KepInitializeSystemResources(); + SystemResources::InitializeResources(); /* Check if debugging enabled */ if(DEBUG) @@ -63,11 +66,11 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION); /* Architecture specific kernel initialization */ - KepInitializeMachine(); + KernelInit::InitializeMachine(); /* Raise to HIGH runlevel */ - KeRaiseRunLevel(HIGH_LEVEL); + RunLevel::RaiseRunLevel(HIGH_LEVEL); /* Switch the boot stack and transfer control to the KepStartKernel() routine */ - KepSwitchBootStack(); + KernelInit::SwitchBootStack(); } diff --git a/xtoskrnl/ke/kthread.c b/xtoskrnl/ke/kthread.cc similarity index 71% rename from xtoskrnl/ke/kthread.c rename to xtoskrnl/ke/kthread.cc index d5c63854..b8ba78a2 100644 --- a/xtoskrnl/ke/kthread.c +++ b/xtoskrnl/ke/kthread.cc @@ -1,14 +1,45 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kthread.c + * FILE: xtoskrnl/ke/kthread.cc * DESCRIPTION: XT kernel thread manipulation support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + +XTAPI +PETHREAD +KThread::GetInitialThread(VOID) +{ + return &InitialThread; +} + +/** + * Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state. + * + * @param OldRunLevel + * Supplies the original runlevel state. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTFASTCALL +VOID +KThread::ExitDispatcher(IN KRUNLEVEL OldRunLevel) +{ + UNIMPLEMENTED; + + /* Lower runlevel */ + RunLevel::LowerRunLevel(OldRunLevel); +} + /** * Initializes the thread. * @@ -42,15 +73,15 @@ */ XTAPI XTSTATUS -KeInitializeThread(IN PKPROCESS Process, - IN OUT PKTHREAD Thread, - IN PKSYSTEM_ROUTINE SystemRoutine, - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext, - IN PCONTEXT Context, - IN PVOID EnvironmentBlock, - IN PVOID Stack, - IN BOOLEAN StartThread) +KThread::InitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID EnvironmentBlock, + IN PVOID Stack, + IN BOOLEAN RunThread) { PKWAIT_BLOCK TimerWaitBlock; BOOLEAN Allocation; @@ -86,10 +117,7 @@ KeInitializeThread(IN PKPROCESS Process, Thread->AdjustReason = AdjustNone; /* Initialize thread lock */ - KeInitializeSpinLock(&Thread->ThreadLock); - - /* Set thread service table */ - Thread->ServiceTable = KeServiceDescriptorTable; + SpinLock::InitializeSpinLock(&Thread->ThreadLock); /* Initialize thread APC */ Thread->ApcStatePointer[0] = &Thread->ApcState; @@ -103,17 +131,17 @@ KeInitializeThread(IN PKPROCESS Process, RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); /* Initialize APC queue lock */ - KeInitializeSpinLock(&Thread->ApcQueueLock); + SpinLock::InitializeSpinLock(&Thread->ApcQueueLock); /* Initialize kernel-mode suspend APC */ - KeInitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, KepSuspendNop, - KepSuspendRundown, KepSuspendThread, KernelMode, NULL); + Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop, + SuspendRundown, SuspendThread, KernelMode, NULL); /* Initialize suspend semaphore */ - KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); + Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); /* Initialize the builtin timer */ - KeInitializeTimer(&Thread->Timer, NotificationTimer); + Timer::InitializeTimer(&Thread->Timer, NotificationTimer); TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK]; TimerWaitBlock->Object = &Thread->Timer; TimerWaitBlock->WaitKey = STATUS_TIMEOUT; @@ -122,7 +150,7 @@ KeInitializeThread(IN PKPROCESS Process, TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead; /* Initialize Thread Environment Block*/ - Thread->EnvironmentBlock = EnvironmentBlock; + Thread->EnvironmentBlock = (PTHREAD_ENVIRONMENT_BLOCK)EnvironmentBlock; /* Make sure there is a valid stack available */ if(!Stack) @@ -141,12 +169,12 @@ KeInitializeThread(IN PKPROCESS Process, Thread->InitialStack = Stack; Thread->StackBase = Stack; - Thread->StackLimit = Stack - KERNEL_STACK_SIZE; + Thread->StackLimit = (PVOID)((ULONG_PTR)Stack - KERNEL_STACK_SIZE); __try { /* Initialize thread context */ - KepInitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context); + InitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context); } __except(EXCEPTION_EXECUTE_HANDLER) { @@ -167,10 +195,10 @@ KeInitializeThread(IN PKPROCESS Process, Thread->State = Initialized; /* Check if thread should be started */ - if(StartThread) + if(RunThread) { /* Start thread */ - KeStartThread(Thread); + StartThread(Thread); } /* Return success */ @@ -189,31 +217,11 @@ KeInitializeThread(IN PKPROCESS Process, */ XTAPI VOID -KeStartThread(IN PKTHREAD Thread) +KThread::StartThread(IN PKTHREAD Thread) { UNIMPLEMENTED; } -/** - * Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state. - * - * @param OldRunLevel - * Supplies the original runlevel state. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTFASTCALL -VOID -KepExitDispatcher(IN KRUNLEVEL OldRunLevel) -{ - UNIMPLEMENTED; - - /* Lower runlevel */ - KeLowerRunLevel(OldRunLevel); -} - /** * Suspend APC-built thread NOP routine. It takes no actions. * @@ -238,11 +246,11 @@ KepExitDispatcher(IN KRUNLEVEL OldRunLevel) */ XTAPI VOID -KepSuspendNop(IN PKAPC Apc, - IN OUT PKNORMAL_ROUTINE *NormalRoutine, - IN OUT PVOID *NormalContext, - IN OUT PVOID *SystemArgument1, - IN OUT PVOID *SystemArgument2) +KThread::SuspendNop(IN PKAPC Apc, + IN OUT PKNORMAL_ROUTINE *NormalRoutine, + IN OUT PVOID *NormalContext, + IN OUT PVOID *SystemArgument1, + IN OUT PVOID *SystemArgument2) { /* No action here */ } @@ -259,7 +267,7 @@ KepSuspendNop(IN PKAPC Apc, */ XTAPI VOID -KepSuspendRundown(IN PKAPC Apc) +KThread::SuspendRundown(IN PKAPC Apc) { /* No action here */ } @@ -282,9 +290,30 @@ KepSuspendRundown(IN PKAPC Apc) */ XTAPI VOID -KepSuspendThread(IN PVOID NormalContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) +KThread::SuspendThread(IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) { UNIMPLEMENTED; } + +} /* namespace */ + + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +XTSTATUS +KeInitializeThread(IN PKPROCESS Process, + IN OUT PKTHREAD Thread, + IN PKSYSTEM_ROUTINE SystemRoutine, + IN PKSTART_ROUTINE StartRoutine, + IN PVOID StartContext, + IN PCONTEXT Context, + IN PVOID EnvironmentBlock, + IN PVOID Stack, + IN BOOLEAN RunThread) +{ + return KE::KThread::InitializeThread(Process, Thread, SystemRoutine, StartRoutine, StartContext, Context, EnvironmentBlock, Stack, RunThread); +} \ No newline at end of file diff --git a/xtoskrnl/ke/kubsan.c b/xtoskrnl/ke/kubsan.cc similarity index 80% rename from xtoskrnl/ke/kubsan.c rename to xtoskrnl/ke/kubsan.cc index 5aa11adf..9fdfa264 100644 --- a/xtoskrnl/ke/kubsan.c +++ b/xtoskrnl/ke/kubsan.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/kubsan.c + * FILE: xtoskrnl/ke/kubsan.cc * DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Checks whether handled UBSAN error should be reported. * @@ -21,10 +25,10 @@ */ XTCDECL BOOLEAN -KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location) +KUbsan::CheckReport(PKUBSAN_SOURCE_LOCATION Location) { /* Make sure, this error should be reported */ - return !KepUbsanActiveFrame; + return (BOOLEAN)!ActiveFrame; } /** @@ -42,11 +46,11 @@ KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location) */ XTCDECL VOID -KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, - PCCHAR Reason) +KUbsan::EnterFrame(PKUBSAN_SOURCE_LOCATION Location, + PCCHAR Reason) { /* Enter UBSAN frame */ - KepUbsanActiveFrame = TRUE; + ActiveFrame = TRUE; /* Print generic error message to debug console */ DebugPrint(L"UBSAN: Undefined behavior (%s) in %s:%d:%d\n", @@ -68,8 +72,8 @@ KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, */ XTCDECL LONGLONG -KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value) +KUbsan::GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value) { ULONG BitWidth, ExtraBits; ULONG_PTR LongValue; @@ -102,7 +106,7 @@ KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, */ XTCDECL PCCHAR -KepGetUbsanTypeKind(UCHAR TypeCheckKind) +KUbsan::GetTypeKind(UCHAR TypeCheckKind) { /* Get type kind name */ switch(TypeCheckKind) @@ -147,8 +151,8 @@ KepGetUbsanTypeKind(UCHAR TypeCheckKind) */ XTCDECL ULONGLONG -KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, - PVOID Value) +KUbsan::GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type, + PVOID Value) { ULONG BitWidth; @@ -184,22 +188,22 @@ KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, */ XTCDECL VOID -KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, - PVOID Lhs, - PVOID Rhs) +KUbsan::HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, + PVOID Lhs, + PVOID Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Division-Overflow"); + EnterFrame(&Data->Location, "Division-Overflow"); /* Check if signed type, which value is -1 */ - if((Data->Type->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->Type, Rhs) == -1)) + if((Data->Type->TypeInfo & 1) && (GetSignedValue(Data->Type, Rhs) == -1)) { /* Division by -1, print error message to debug console */ DebugPrint(L"UBSAN: Division by -1 cannot be represented in type %s\n", Data->Type->TypeName); @@ -211,7 +215,7 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -232,25 +236,25 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KUbsan::HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); + EnterFrame(&Data->Location, "Float-Cast-Overflow"); /* Print error message to debug console */ DebugPrint(L"Value of type %s is outside the range of type %s\n", Data->LhsType->TypeName, Data->RhsType->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -268,25 +272,25 @@ KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KUbsan::HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); + EnterFrame(&Data->Location, "Float-Cast-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Indirect function call through %P address of a wrong type %s\n", (PVOID)Pointer, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -307,25 +311,25 @@ KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KUbsan::HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Integer-Overflow"); + EnterFrame(&Data->Location, "Integer-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: The result of an arithmetic operation cannot be represented in type %s\n", Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -340,17 +344,17 @@ KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) +KUbsan::HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Invalid-Builtin"); + EnterFrame(&Data->Location, "Invalid-Builtin"); /* Check kind of UBSAN error */ if(Data->Kind == 0 || Data->Kind == 1) @@ -365,7 +369,7 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -383,25 +387,25 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) */ XTCDECL VOID -KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KUbsan::HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Misaligned-Access"); + EnterFrame(&Data->Location, "Misaligned-Access"); /* Print error message to debug console */ DebugPrint(L"UBSAN: %s misaligned address %p for type %s which requires %ld byte alignment\n", - KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment); + GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -419,24 +423,24 @@ KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR OldValue) +KUbsan::HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR OldValue) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Negate-Overflow"); + EnterFrame(&Data->Location, "Negate-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Negation of %lu cannot be represented in type %s\n", OldValue, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } @@ -455,23 +459,23 @@ KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) +KUbsan::HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "NULL-Pointer-Dereference"); + EnterFrame(&Data->Location, "NULL-Pointer-Dereference"); /* Print error message to debug console */ - DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", KepGetUbsanTypeKind(Data->TypeCheckKind), Data->Type->TypeName); + DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", GetTypeKind(Data->TypeCheckKind), Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -489,25 +493,25 @@ KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) */ XTCDECL VOID -KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, +KUbsan::HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, ULONG_PTR Pointer) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Object-Size-Mismatch"); + EnterFrame(&Data->Location, "Object-Size-Mismatch"); /* Print error message to debug console */ DebugPrint(L"UBSAN: %s address %p with insufficient space for an object of type %s\n", - KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName); + GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -525,24 +529,24 @@ KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Index) +KUbsan::HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Index) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Array-Index-Out-Of-Bounds"); + EnterFrame(&Data->Location, "Array-Index-Out-Of-Bounds"); /* Print error message to debug console */ DebugPrint(L"UBSAN: index is out of range for type %s", Data->ArrayType->TypeName); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -563,26 +567,26 @@ KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, */ XTCDECL VOID -KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KUbsan::HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Pointer-Overflow"); + EnterFrame(&Data->Location, "Pointer-Overflow"); /* Print error message to debug console */ DebugPrint(L"UBSAN: Pointer operation %s %p to %p\n", Lhs > Rhs ? "overflowed" : "underflowed", (PVOID)Lhs, (PVOID)Rhs); /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } @@ -604,52 +608,52 @@ KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, */ XTCDECL VOID -KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, - ULONG_PTR Lhs, - ULONG_PTR Rhs) +KUbsan::HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, + ULONG_PTR Lhs, + ULONG_PTR Rhs) { ULONG LhsBitWidth; /* Check if this error was already reported */ - if(!KepCheckUbsanReport(&Data->Location)) + if(!CheckReport(&Data->Location)) { /* Don't report twice */ return; } /* Enter UBSAN frame */ - KepEnterUbsanFrame(&Data->Location, "Shift-Out-Of-Bounds"); + EnterFrame(&Data->Location, "Shift-Out-Of-Bounds"); /* Calculate Lhs bit width */ LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1); /* Check a type of out of bounds error */ - if((Data->RhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs) < 0)) + if((Data->RhsType->TypeInfo & 1) && (GetSignedValue(Data->RhsType, (PVOID)Rhs) < 0)) { /* Negative shift exponent, print error message to debug console */ - DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs)); + DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", GetSignedValue(Data->RhsType, (PVOID)Rhs)); } - else if((Data->LhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs) < 0)) + else if((Data->LhsType->TypeInfo & 1) && (GetSignedValue(Data->LhsType, (PVOID)Lhs) < 0)) { /* Negative left shift value, print error message to debug console */ - DebugPrint(L"UBSAN: Left shift of negative value %lld\n", KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs)); + DebugPrint(L"UBSAN: Left shift of negative value %lld\n", GetSignedValue(Data->LhsType, (PVOID)Lhs)); } - else if(KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth) + else if(GetUnsignedValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth) { /* Shift exponent too large, print error message to debug console */ DebugPrint(L"UBSAN: Shift exponent %lld is too large for %u-bit type %s\n", - KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName); + GetUnsignedValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName); } else { /* Left shift too large, print error message to debug console */ DebugPrint(L"UBSAN: Left shift of %lld by %lld places cannot be represented in type %s\n", - KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs), KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs), + GetSignedValue(Data->LhsType, (PVOID)Lhs), GetSignedValue(Data->RhsType, (PVOID)Rhs), Data->LhsType->TypeName); } /* Leave UBSAN frame */ - KepLeaveUbsanFrame(); + LeaveFrame(); } /** @@ -667,24 +671,24 @@ KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, */ XTCDECL VOID -KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, - ULONG_PTR Pointer) +KUbsan::HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, + ULONG_PTR Pointer) { /* Check the type of mismatch */ if(!Pointer) { /* Handle NULL pointer dereference */ - KepHandleUbsanNullPointerDereference(Data); + HandleNullPointerDereference(Data); } - else if(Data->Alignment && (((Pointer) & ((typeof(Pointer))(Data->Alignment) - 1)) != 0)) + else if(Data->Alignment && (((Pointer) & ((decltype(Pointer))(Data->Alignment) - 1)) != 0)) { /* Handle misaligned access */ - KepHandleUbsanMisalignedAccess(Data, Pointer); + HandleMisalignedAccess(Data, Pointer); } else { /* Handle object size mismatch */ - KepHandleUbsanObjectSizeMismatch(Data, Pointer); + HandleObjectSizeMismatch(Data, Pointer); } } @@ -697,12 +701,17 @@ KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, */ XTCDECL VOID -KepLeaveUbsanFrame() +KUbsan::LeaveFrame() { /* Leave UBSAN frame */ - KepUbsanActiveFrame = FALSE; + ActiveFrame = FALSE; } +} /* namespace */ + + + + /** * Handles the addition overflow error. This is internal routine implementing ABI defined by CLANG UBSAN. * @@ -721,6 +730,7 @@ KepLeaveUbsanFrame() * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -728,7 +738,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -749,6 +759,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, * * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113 */ +XTCLINK XTCDECL VOID __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, @@ -756,7 +767,7 @@ __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN PVOID Rhs) { /* Call UBSAN division overflow handler */ - KepHandleUbsanDivisionOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleDivisionOverflow(Data, Lhs, Rhs); } /** @@ -784,7 +795,7 @@ __ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN float cast overflow handler */ - KepHandleUbsanFloatCastOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleFloatCastOverflow(Data, Lhs, Rhs); } /** @@ -808,7 +819,7 @@ __ubsan_handle_function_type_mismatch(IN PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Dat IN ULONG_PTR Pointer) { /* Call UBSAN function type mismatch handler */ - KepHandleUbsanFunctionTypeMismatch(Data, Pointer); + KE::KUbsan::HandleFunctionTypeMismatch(Data, Pointer); } /** @@ -828,7 +839,7 @@ VOID __ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data) { /* Call UBSAN invalid builtin handler */ - KepHandleUbsanInvalidBuiltin(Data); + KE::KUbsan::HandleInvalidBuiltin(Data); } /** @@ -856,7 +867,7 @@ __ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -880,7 +891,7 @@ __ubsan_handle_negate_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR OldValue) { /* Call UBSAN negate overflow handler */ - KepHandleUbsanNegateOverflow(Data, OldValue); + KE::KUbsan::HandleNegateOverflow(Data, OldValue); } /** @@ -904,7 +915,7 @@ __ubsan_handle_out_of_bounds(IN PKUBSAN_OUT_OF_BOUNDS_DATA Data, IN ULONG_PTR Index) { /* Call UBSAN out of bounds handler */ - KepHandleUbsanOutOfBounds(Data, Index); + KE::KUbsan::HandleOutOfBounds(Data, Index); } /** @@ -932,7 +943,7 @@ __ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN pointer overflow handler */ - KepHandleUbsanPointerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandlePointerOverflow(Data, Lhs, Rhs); } /** @@ -960,7 +971,7 @@ __ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN out of bounds handler */ - KepHandleUbsanShiftOutOfBounds(Data, Lhs, Rhs); + KE::KUbsan::HandleShiftOutOfBounds(Data, Lhs, Rhs); } /** @@ -988,7 +999,7 @@ __ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data, IN ULONG_PTR Rhs) { /* Call UBSAN arithmetic overflow handler */ - KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs); + KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs); } /** @@ -1012,7 +1023,7 @@ __ubsan_handle_type_mismatch(IN PKUBSAN_TYPE_MISMATCH_DATA Data, IN ULONG_PTR Pointer) { /* Call UBSAN type mismatch handler */ - KepHandleUbsanTypeMismatch(Data, Pointer); + KE::KUbsan::HandleTypeMismatch(Data, Pointer); } /** @@ -1044,5 +1055,5 @@ __ubsan_handle_type_mismatch_v1(IN PKUBSAN_TYPE_MISMATCH_DATA_V1 Data, MismatchData.TypeCheckKind = Data->TypeCheckKind; /* Call UBSAN type mismatch handler */ - KepHandleUbsanTypeMismatch(&MismatchData, Pointer); + KE::KUbsan::HandleTypeMismatch(&MismatchData, Pointer); } diff --git a/xtoskrnl/ke/runlevel.c b/xtoskrnl/ke/runlevel.cc similarity index 68% rename from xtoskrnl/ke/runlevel.c rename to xtoskrnl/ke/runlevel.cc index 4a6a548e..601fb40f 100644 --- a/xtoskrnl/ke/runlevel.c +++ b/xtoskrnl/ke/runlevel.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/runlevel.c + * FILE: xtoskrnl/ke/runlevel.cc * DESCRIPTION: Running Level management support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Gets the current running level of the current processor. * @@ -18,7 +22,7 @@ */ XTFASTCALL KRUNLEVEL -KeGetCurrentRunLevel(VOID) +RunLevel::GetCurrentRunLevel(VOID) { return HlGetRunLevel(); } @@ -35,7 +39,7 @@ KeGetCurrentRunLevel(VOID) */ XTFASTCALL VOID -KeLowerRunLevel(IN KRUNLEVEL RunLevel) +RunLevel::LowerRunLevel(IN KRUNLEVEL RunLevel) { KRUNLEVEL OldRunLevel; @@ -62,7 +66,7 @@ KeLowerRunLevel(IN KRUNLEVEL RunLevel) */ XTFASTCALL KRUNLEVEL -KeRaiseRunLevel(IN KRUNLEVEL RunLevel) +RunLevel::RaiseRunLevel(IN KRUNLEVEL RunLevel) { KRUNLEVEL OldRunLevel; @@ -79,3 +83,33 @@ KeRaiseRunLevel(IN KRUNLEVEL RunLevel) /* Return old run level */ return OldRunLevel; } + +} /* namespace */ + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTFASTCALL +KRUNLEVEL +KeGetCurrentRunLevel(VOID) +{ + return KE::RunLevel::GetCurrentRunLevel(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTFASTCALL +VOID +KeLowerRunLevel(KRUNLEVEL RunLevel) +{ + KE::RunLevel::LowerRunLevel(RunLevel); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTFASTCALL +KRUNLEVEL +KeRaiseRunLevel(KRUNLEVEL RunLevel) +{ + return KE::RunLevel::RaiseRunLevel(RunLevel); +} diff --git a/xtoskrnl/ke/semphore.c b/xtoskrnl/ke/semphore.cc similarity index 76% rename from xtoskrnl/ke/semphore.c rename to xtoskrnl/ke/semphore.cc index 2e95ce9a..aa4d50f1 100644 --- a/xtoskrnl/ke/semphore.c +++ b/xtoskrnl/ke/semphore.cc @@ -1,16 +1,19 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/semphore.c + * FILE: xtoskrnl/ke/semphore.cc * DESCRIPTION: Semaphores support * DEVELOPERS: Rafal Kupiec */ -#include +#include +namespace KE +{ + /** - * initializes a kernel semaphore object. + * Initializes a kernel semaphore object. * * @param Semaphore * Supplies a pointer to a semaphore object. @@ -27,9 +30,9 @@ */ XTAPI VOID -KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, - IN LONG Count, - IN LONG Limit) +Semaphore::InitializeSemaphore(IN PKSEMAPHORE Semaphore, + IN LONG Count, + IN LONG Limit) { /* Initialize semaphore header and limit */ Semaphore->Header.Type = SemaphoreObject; @@ -52,7 +55,7 @@ KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, */ XTAPI LONG -KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) +Semaphore::ReadState(IN PKSEMAPHORE Semaphore) { /* Return semaphore's signal state */ return Semaphore->Header.SignalState; @@ -79,11 +82,13 @@ KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) */ XTAPI LONG -KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, - IN KPRIORITY Increment, - IN LONG Adjustment, - IN BOOLEAN Wait) +Semaphore::ReleaseSemaphore(IN PKSEMAPHORE Semaphore, + IN KPRIORITY Increment, + IN LONG Adjustment, + IN BOOLEAN Wait) { UNIMPLEMENTED; return 0; } + +} /* namespace */ diff --git a/xtoskrnl/ke/spinlock.c b/xtoskrnl/ke/spinlock.cc similarity index 76% rename from xtoskrnl/ke/spinlock.c rename to xtoskrnl/ke/spinlock.cc index 5d11bfda..f9e4684d 100644 --- a/xtoskrnl/ke/spinlock.c +++ b/xtoskrnl/ke/spinlock.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/spinlock.c + * FILE: xtoskrnl/ke/spinlock.cc * DESCRIPTION: Spinlocks support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Acquires a specified queued spinlock. * @@ -21,10 +25,10 @@ */ XTFASTCALL VOID -KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +SpinLock::AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) { /* Acquire the queued spinlock */ - KeAcquireSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); + AcquireSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); } /** @@ -39,7 +43,7 @@ KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) */ XTFASTCALL VOID -KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) +SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) { /* Try to acquire the lock */ while(RtlAtomicBitTestAndSet((PLONG)SpinLock, 0)) @@ -68,7 +72,7 @@ KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) */ XTAPI VOID -KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) +SpinLock::InitializeSpinLock(IN PKSPIN_LOCK SpinLock) { /* Zero initialize spinlock */ *SpinLock = 0; @@ -86,10 +90,10 @@ KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) */ XTFASTCALL VOID -KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) +SpinLock::ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) { /* Clear the lock */ - KeReleaseSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); + ReleaseSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock); } /** @@ -104,7 +108,7 @@ KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) */ XTFASTCALL VOID -KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) +SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) { /* Clear the lock */ RtlAtomicAnd32((PLONG)SpinLock, 0); @@ -112,3 +116,5 @@ KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) /* Add an explicit memory barrier */ ArReadWriteBarrier(); } + +} /* namespace */ diff --git a/xtoskrnl/ke/sysres.c b/xtoskrnl/ke/sysres.cc similarity index 73% rename from xtoskrnl/ke/sysres.c rename to xtoskrnl/ke/sysres.cc index bf45dc36..0cccdebe 100644 --- a/xtoskrnl/ke/sysres.c +++ b/xtoskrnl/ke/sysres.cc @@ -1,15 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/sysres.c + * FILE: xtoskrnl/ke/sysres.cc * DESCRIPTION: System resources management; This code is based on the MinocaOS implementation - * Copyright(C) 2012 Minoca Corp. (https://github.com/minoca/os/blob/master/kernel/ke/sysres.c) * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Kernel Library */ +namespace KE +{ + /** * Looks for an unacquired system resource of the specified type and acquires it. * @@ -25,59 +28,11 @@ */ XTAPI XTSTATUS -KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) { /* Get system resource and acquire an ownership */ - return KepGetSystemResource(ResourceType, TRUE, ResourceHeader); -} - -/** - * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. - * - * @param ResourceType - * Supplies system resource type. - * - * @param ResourceHeader - * Specifies a memory area where a pointer to the system resource header will be stored. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) -{ - /* Get system resource without acquiring an ownership */ - return KepGetSystemResource(ResourceType, FALSE, ResourceHeader); -} - -/** - * Releases system resource. - * - * @param ResourceHeader - * Specifies a pointer to the system resource header. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) -{ - /* Disable interrupts and acquire a spinlock */ - ArClearInterruptFlag(); - KeAcquireSpinLock(&KepSystemResourcesLock); - - /* Release resource lock */ - ResourceHeader->ResourceLocked = FALSE; - - /* Release spinlock and enable interrupts */ - KeReleaseSpinLock(&KepSystemResourcesLock); - ArSetInterruptFlag(); + return GetSystemResource(ResourceType, TRUE, ResourceHeader); } /** @@ -98,9 +53,9 @@ KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) */ XTAPI XTSTATUS -KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, - IN BOOLEAN ResourceLock, - OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + IN BOOLEAN ResourceLock, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) { PSYSTEM_RESOURCE_HEADER Resource; PLIST_ENTRY ListEntry; @@ -111,15 +66,15 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, Status = STATUS_SUCCESS; /* Check if interrupts are enabled */ - Interrupts = ArInterruptsEnabled(); + Interrupts = AR::CpuFunc::InterruptsEnabled(); /* Disable interrupts and acquire a spinlock */ - ArClearInterruptFlag(); - KeAcquireSpinLock(&KepSystemResourcesLock); + AR::CpuFunc::ClearInterruptFlag(); + SpinLock::AcquireSpinLock(&ResourcesLock); /* Iterate through system resources list */ - ListEntry = KepSystemResourcesListHead.Flink; - while(ListEntry != &KepSystemResourcesListHead) + ListEntry = ResourcesListHead.Flink; + while(ListEntry != &ResourcesListHead) { /* Get resource header */ Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); @@ -151,19 +106,19 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, } /* Check if resource was found */ - if(ListEntry == &KepSystemResourcesListHead) + if(ListEntry == &ResourcesListHead) { /* Resource not found, return NULL */ - Resource = NULL; + Resource = nullptr; Status = STATUS_NOT_FOUND; } /* Release spinlock and re-enable interrupts if necessary */ - KeReleaseSpinLock(&KepSystemResourcesLock); + SpinLock::ReleaseSpinLock(&ResourcesLock); if(Interrupts) { /* Re-enable interrupts */ - ArSetInterruptFlag(); + AR::CpuFunc::SetInterruptFlag(); } /* Return resource header and status code */ @@ -171,6 +126,28 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, return Status; } +/** + * Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership. + * + * @param ResourceType + * Supplies system resource type. + * + * @param ResourceHeader + * Specifies a memory area where a pointer to the system resource header will be stored. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType, + OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) +{ + /* Get system resource without acquiring an ownership */ + return GetSystemResource(ResourceType, FALSE, ResourceHeader); +} + /** * Initializes system resource management. * @@ -180,22 +157,22 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, */ XTAPI VOID -KepInitializeSystemResources(VOID) +SystemResources::InitializeResources(VOID) { PSYSTEM_RESOURCE_HEADER ResourceHeader; PLIST_ENTRY ListEntry, NextListEntry; ULONG ResourceSize; /* Initialize system resources spin lock and resource list */ - KeInitializeSpinLock(&KepSystemResourcesLock); - RtlInitializeListHead(&KepSystemResourcesListHead); + SpinLock::InitializeSpinLock(&ResourcesLock); + RtlInitializeListHead(&ResourcesListHead); /* Make sure there are some system resources available */ - if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead)) + if(!RtlListEmpty(BootInformation::GetSystemResources())) { /* Iterate through system resources list */ - ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink; - while(ListEntry != &KeInitializationBlock->SystemResourcesListHead) + ListEntry = BootInformation::GetSystemResources()->Flink; + while(ListEntry != BootInformation::GetSystemResources()) { /* Get resource header and next list entry */ ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); @@ -223,7 +200,7 @@ KepInitializeSystemResources(VOID) { /* Move valid resource to the internal kernel list of system resources */ RtlRemoveEntryList(&ResourceHeader->ListEntry); - RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry); + RtlInsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry); } /* Go to the next list entry */ @@ -231,3 +208,31 @@ KepInitializeSystemResources(VOID) } } } + +/** + * Releases boot system resource. + * + * @param ResourceHeader + * Specifies a pointer to the boot system resource header. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) +{ + /* Disable interrupts and acquire a spinlock */ + AR::CpuFunc::ClearInterruptFlag(); + SpinLock::AcquireSpinLock(&ResourcesLock); + + /* Release resource lock */ + ResourceHeader->ResourceLocked = FALSE; + + /* Release spinlock and enable interrupts */ + SpinLock::ReleaseSpinLock(&ResourcesLock); + AR::CpuFunc::SetInterruptFlag(); +} + +} /* namespace */ diff --git a/xtoskrnl/ke/timer.c b/xtoskrnl/ke/timer.cc similarity index 80% rename from xtoskrnl/ke/timer.c rename to xtoskrnl/ke/timer.cc index 8c7bbeee..2ce5c3f0 100644 --- a/xtoskrnl/ke/timer.c +++ b/xtoskrnl/ke/timer.cc @@ -1,14 +1,17 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ke/timer.c + * FILE: xtoskrnl/ke/timer.cc * DESCRIPTION: Kernel timer object support * DEVELOPERS: Rafal Kupiec */ -#include +#include +namespace KE +{ + /** * Cancels the timer. * @@ -21,7 +24,7 @@ */ XTAPI BOOLEAN -KeCancelTimer(IN PKTIMER Timer) +Timer::CancelTimer(IN PKTIMER Timer) { BOOLEAN Result; KRUNLEVEL RunLevel; @@ -31,19 +34,19 @@ KeCancelTimer(IN PKTIMER Timer) /* Raise run level and acquire dispatcher lock */ RunLevel = KeRaiseRunLevel(SYNC_LEVEL); - KeAcquireQueuedSpinLock(DispatcherLock); + SpinLock::AcquireQueuedSpinLock(DispatcherLock); /* Check timer status */ if(Timer->Header.Inserted) { /* Remove the timer from the list */ - KepRemoveTimer(Timer); + RemoveTimer(Timer); Result = TRUE; } /* Release dispatcher lock and process the deferred ready list */ - KeReleaseQueuedSpinLock(DispatcherLock); - KepExitDispatcher(RunLevel); + SpinLock::ReleaseQueuedSpinLock(DispatcherLock); + KThread::ExitDispatcher(RunLevel); /* Return result */ return Result; @@ -61,7 +64,7 @@ KeCancelTimer(IN PKTIMER Timer) */ XTAPI VOID -KeClearTimer(IN PKTIMER Timer) +Timer::ClearTimer(IN PKTIMER Timer) { /* Clear signal state */ Timer->Header.SignalState = 0; @@ -79,7 +82,7 @@ KeClearTimer(IN PKTIMER Timer) */ XTAPI BOOLEAN -KeGetTimerState(IN PKTIMER Timer) +Timer::GetState(IN PKTIMER Timer) { /* Return timer state */ return (BOOLEAN)Timer->Header.SignalState; @@ -100,11 +103,11 @@ KeGetTimerState(IN PKTIMER Timer) */ XTAPI VOID -KeInitializeTimer(OUT PKTIMER Timer, - IN KTIMER_TYPE Type) +Timer::InitializeTimer(OUT PKTIMER Timer, + IN KTIMER_TYPE Type) { /* Initialize the header */ - Timer->Header.Type = TimerNotificationObject + Type; + Timer->Header.Type = TimerNotificationObject + (UCHAR)Type; Timer->Header.Inserted = 0; Timer->Header.SignalState = 0; @@ -129,7 +132,7 @@ KeInitializeTimer(OUT PKTIMER Timer, */ XTAPI ULONGLONG -KeQueryTimer(IN PKTIMER Timer) +Timer::QueryTimer(IN PKTIMER Timer) { KRUNLEVEL RunLevel; ULONGLONG DueTime; @@ -139,7 +142,7 @@ KeQueryTimer(IN PKTIMER Timer) /* Raise run level and acquire dispatcher lock */ RunLevel = KeRaiseRunLevel(SYNC_LEVEL); - KeAcquireQueuedSpinLock(DispatcherLock); + SpinLock::AcquireQueuedSpinLock(DispatcherLock); /* Check timer status */ if(Timer->Header.Inserted) @@ -149,8 +152,8 @@ KeQueryTimer(IN PKTIMER Timer) } /* Release dispatcher lock and process the deferred ready list */ - KeReleaseQueuedSpinLock(DispatcherLock); - KepExitDispatcher(RunLevel); + SpinLock::ReleaseQueuedSpinLock(DispatcherLock); + KThread::ExitDispatcher(RunLevel); /* Return timer's due time */ return DueTime; @@ -177,10 +180,10 @@ KeQueryTimer(IN PKTIMER Timer) */ XTAPI VOID -KeSetTimer(IN PKTIMER Timer, - IN LARGE_INTEGER DueTime, - IN LONG Period, - IN PKDPC Dpc) +Timer::SetTimer(IN PKTIMER Timer, + IN LARGE_INTEGER DueTime, + IN LONG Period, + IN PKDPC Dpc) { UNIMPLEMENTED; } @@ -197,9 +200,11 @@ KeSetTimer(IN PKTIMER Timer, */ XTAPI VOID -KepRemoveTimer(IN OUT PKTIMER Timer) +Timer::RemoveTimer(IN OUT PKTIMER Timer) { /* Remove the timer from the list */ Timer->Header.Inserted = FALSE; RtlRemoveEntryList(&Timer->TimerListEntry); } + +} /* namespace */ diff --git a/xtoskrnl/mm/hlpool.c b/xtoskrnl/mm/hlpool.c index 5b96fa99..a5302b9f 100644 --- a/xtoskrnl/mm/hlpool.c +++ b/xtoskrnl/mm/hlpool.c @@ -50,8 +50,8 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, } /* Scan memory descriptors provided by the boot loader */ - ListEntry = KeInitializationBlock->MemoryDescriptorListHead.Flink; - while(ListEntry != &KeInitializationBlock->MemoryDescriptorListHead) + ListEntry = KeGetInitializationBlock()->MemoryDescriptorListHead.Flink; + while(ListEntry != &KeGetInitializationBlock()->MemoryDescriptorListHead) { Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry); @@ -77,7 +77,7 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount, } /* Make sure we found a descriptor */ - if(ListEntry == &KeInitializationBlock->MemoryDescriptorListHead) + if(ListEntry == &KeGetInitializationBlock()->MemoryDescriptorListHead) { /* Descriptor not found, return error */ return STATUS_INSUFFICIENT_RESOURCES; diff --git a/xtoskrnl/mm/init.c b/xtoskrnl/mm/init.c index a0917b94..3225c163 100644 --- a/xtoskrnl/mm/init.c +++ b/xtoskrnl/mm/init.c @@ -54,8 +54,8 @@ MmpScanMemoryDescriptors(VOID) FreePages = 0; /* Iterate through memory mappings provided by the boot loader */ - MemoryMappings = KeInitializationBlock->MemoryDescriptorListHead.Flink; - while(MemoryMappings != &KeInitializationBlock->MemoryDescriptorListHead) + MemoryMappings = KeGetInitializationBlock()->MemoryDescriptorListHead.Flink; + while(MemoryMappings != &KeGetInitializationBlock()->MemoryDescriptorListHead) { /* Get memory descriptor */ MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry);