C to C++ migration and refactoring #17

Merged
harraiken merged 67 commits from cxxtest into master 2025-09-24 20:18:35 +02:00
52 changed files with 2213 additions and 710 deletions
Showing only changes of commit 4947f788d5 - Show all commits

View File

@@ -52,6 +52,7 @@ typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
typedef enum _MODE MODE, *PMODE; typedef enum _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; 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_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; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
/* Structures forward references */ /* Structures forward references */

View File

@@ -43,25 +43,27 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c ${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c
${XTOSKRNL_SOURCE_DIR}/kd/globals.c ${XTOSKRNL_SOURCE_DIR}/kd/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/apc.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/ke/dpc.c ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/event.c ${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/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/info.c ${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c ${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c ${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc
${XTOSKRNL_SOURCE_DIR}/ke/kthread.c ${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.c ${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
${XTOSKRNL_SOURCE_DIR}/ke/panic.c ${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c ${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
${XTOSKRNL_SOURCE_DIR}/ke/semphore.c ${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c ${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
${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}/mm/globals.c ${XTOSKRNL_SOURCE_DIR}/mm/globals.c
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c ${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c
${XTOSKRNL_SOURCE_DIR}/mm/init.c ${XTOSKRNL_SOURCE_DIR}/mm/init.c

View File

@@ -306,9 +306,9 @@ ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */ /* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = nullptr; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial MXCSR register value */ /* Set initial MXCSR register value */

View File

@@ -303,9 +303,9 @@ ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */ /* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = nullptr; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial runlevel */ /* Set initial runlevel */

View File

@@ -9,6 +9,7 @@
#include <xtos.hh> #include <xtos.hh>
/* Kernel Executive */
namespace EX namespace EX
{ {
@@ -139,7 +140,7 @@ Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count)) if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count))
{ {
KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE); KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE);
} }
break; break;

31
xtoskrnl/includes/ke.hh Normal file
View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_HH
#define __XTOSKRNL_KE_HH
#include <xtos.hh>
#include <ke/apc.hh>
#include <ke/bootinfo.hh>
#include <ke/crash.hh>
#include <ke/dpc.hh>
#include <ke/event.hh>
#include <ke/irq.hh>
#include <ke/kprocess.hh>
#include <ke/krnlinit.hh>
#include <ke/kthread.hh>
#include <ke/kubsan.hh>
#include <ke/proc.hh>
#include <ke/runlevel.hh>
#include <ke/semphore.hh>
#include <ke/spinlock.hh>
#include <ke/sysres.hh>
#include <ke/timer.hh>
#endif /* __XTOSKRNL_KE_HH */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_APC_HH
#define __XTOSKRNL_KE_APC_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_BOOTINFO_HH
#define __XTOSKRNL_KE_BOOTINFO_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_CRASH_HH
#define __XTOSKRNL_KE_CRASH_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_DPC_HH
#define __XTOSKRNL_KE_DPC_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_EVENT_HH
#define __XTOSKRNL_KE_EVENT_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_INFO_HH
#define __XTOSKRNL_KE_INFO_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_IRQ_HH
#define __XTOSKRNL_KE_IRQ_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Irq
{
public:
STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler);
};
}
#endif /* __XTOSKRNL_KE_IRQ_HH */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KPROCESS_HH
#define __XTOSKRNL_KE_KPROCESS_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KRNLINIT_HH
#define __XTOSKRNL_KE_KRNLINIT_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KTHREAD_HH
#define __XTOSKRNL_KE_KTHREAD_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KUBSAN_HH
#define __XTOSKRNL_KE_KUBSAN_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_PROC_HH
#define __XTOSKRNL_KE_PROC_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_RUNLEVEL_HH
#define __XTOSKRNL_KE_RUNLEVEL_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SEMPHORE_HH
#define __XTOSKRNL_KE_SEMPHORE_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SPINLOCK_HH
#define __XTOSKRNL_KE_SPINLOCK_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SYSRES_HH
#define __XTOSKRNL_KE_SYSRES_HH
#include <xtos.hh>
/* 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 */

View File

@@ -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 <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_TIMER_HH
#define __XTOSKRNL_KE_TIMER_HH
#include <xtos.hh>
/* 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 */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: Kernel interrupts support for amd64 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Sets new interrupt handler for the existing IDT entry. * Sets new interrupt handler for the existing IDT entry.
* *
@@ -24,7 +28,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeSetInterruptHandler(IN ULONG Vector, Irq::SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler) IN PVOID Handler)
{ {
PKPROCESSOR_BLOCK ProcessorBlock; 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].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32; 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);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: CPU architecture specific kernel initialization
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* This routine initializes XT kernel. * This routine initializes XT kernel.
* *
@@ -18,7 +22,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeKernel(VOID) KernelInit::InitializeKernel(VOID)
{ {
XTSTATUS Status; XTSTATUS Status;
@@ -28,7 +32,7 @@ KepInitializeKernel(VOID)
{ {
/* Hardware layer initialization failed, kernel panic */ /* Hardware layer initialization failed, kernel panic */
DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
KePanic(0); Crash::Panic(0);
} }
} }
@@ -41,7 +45,7 @@ KepInitializeKernel(VOID)
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeMachine(VOID) KernelInit::InitializeMachine(VOID)
{ {
/* Re-enable IDE interrupts */ /* Re-enable IDE interrupts */
HlIoPortOutByte(0x376, 0); HlIoPortOutByte(0x376, 0);
@@ -66,7 +70,7 @@ KepInitializeMachine(VOID)
*/ */
XTAPI XTAPI
VOID VOID
KepStartKernel(VOID) KernelInit::StartKernel(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
ULONG_PTR PageDirectory[2]; ULONG_PTR PageDirectory[2];
@@ -74,8 +78,8 @@ KepStartKernel(VOID)
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
/* Get processor control block and current thread */ /* Get processor control block and current thread */
Prcb = KeGetCurrentProcessorControlBlock(); Prcb = Processor::GetCurrentProcessorControlBlock();
CurrentThread = KeGetCurrentThread(); CurrentThread = Processor::GetCurrentThread();
/* Get current process */ /* Get current process */
CurrentProcess = CurrentThread->ApcState.Process; CurrentProcess = CurrentThread->ApcState.Process;
@@ -84,23 +88,22 @@ KepStartKernel(VOID)
PoInitializeProcessorControlBlock(Prcb); PoInitializeProcessorControlBlock(Prcb);
/* Save processor state */ /* Save processor state */
KepSaveProcessorState(&Prcb->ProcessorState); Processor::SaveProcessorState(&Prcb->ProcessorState);
/* Lower to APC runlevel */ /* Lower to APC runlevel */
KeLowerRunLevel(APC_LEVEL); RunLevel::LowerRunLevel(APC_LEVEL);
/* Initialize XTOS kernel */ /* Initialize XTOS kernel */
KepInitializeKernel(); InitializeKernel();
/* Initialize Idle process */ /* Initialize Idle process */
RtlInitializeListHead(&KepProcessListHead);
PageDirectory[0] = 0; PageDirectory[0] = 0;
PageDirectory[1] = 0; PageDirectory[1] = 0;
KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
CurrentProcess->Quantum = MAXCHAR; CurrentProcess->Quantum = MAXCHAR;
/* Initialize Idle thread */ /* 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; CurrentThread->State = Running;
@@ -109,12 +112,12 @@ KepStartKernel(VOID)
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
/* Enter infinite loop */ /* Enter infinite loop */
DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
for(;;); 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. * @return This routine does not return any value.
* *
@@ -122,20 +125,28 @@ KepStartKernel(VOID)
*/ */
XTAPI XTAPI
VOID 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 Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); 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" __asm__ volatile("mov %0, %%rdx\n"
"xor %%rbp, %%rbp\n" "xor %%rbp, %%rbp\n"
"mov %%rdx, %%rsp\n" "mov %%rdx, %%rsp\n"
"sub %1, %%rsp\n" "sub %1, %%rsp\n"
"jmp KepStartKernel\n" "jmp *%2\n"
: :
: "m" (Stack), : "m" (Stack),
"i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
"p" (KepStartKernel) "r" (StartKernel)
: "rdx", "rbp", "rsp", "memory"); : "rdx", "rbp", "rsp", "memory");
} }
} /* namespace */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: AMD64 thread manipulation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Initializes CPU architecture dependent context of a thread. * Initializes CPU architecture dependent context of a thread.
* *
@@ -33,7 +37,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeThreadContext(IN PKTHREAD Thread, KThread::InitializeThreadContext(IN PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine, IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext, IN PVOID StartContext,
@@ -116,3 +120,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread,
/* Set thread stack */ /* Set thread stack */
Thread->KernelStack = &ThreadFrame->SwitchFrame; Thread->KernelStack = &ThreadFrame->SwitchFrame;
} }
} /* namespace */

View File

@@ -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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* 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);
}

162
xtoskrnl/ke/amd64/proc.cc Normal file
View File

@@ -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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* 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);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/apc.c * FILE: xtoskrnl/ke/apc.cc
* DESCRIPTION: Kernel APC objects support * DESCRIPTION: Kernel APC objects support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Initializes an APC object. * Initializes an APC object.
* *
@@ -42,7 +46,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeApc(IN PKAPC Apc, Apc::InitializeApc(IN PKAPC Apc,
IN PKTHREAD Thread, IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment, IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine, IN PKKERNEL_ROUTINE KernelRoutine,
@@ -89,3 +93,5 @@ KeInitializeApc(IN PKAPC Apc,
/* Mark APC as not inserted yet */ /* Mark APC as not inserted yet */
Apc->Inserted = FALSE; Apc->Inserted = FALSE;
} }
} /* namespace */

View File

@@ -1,14 +1,25 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/info.c * FILE: xtoskrnl/ke/bootinfo.cc
* DESCRIPTION: Generic kernel information support * DESCRIPTION: Bootloader-provided system information handling support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com> * DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
XTAPI
PVOID
BootInformation::GetDebugPrint(VOID)
{
return InitializationBlock->LoaderInformation.DbgPrint;
}
/** /**
* Retrieves the system firmware type (BIOS or UEFI). * Retrieves the system firmware type (BIOS or UEFI).
* *
@@ -18,9 +29,9 @@
*/ */
XTAPI XTAPI
SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE
KeGetFirmwareType(VOID) BootInformation::GetFirmwareType(VOID)
{ {
return KeInitializationBlock->FirmwareInformation.FirmwareType; return InitializationBlock->FirmwareInformation.FirmwareType;
} }
/** /**
@@ -38,17 +49,14 @@ KeGetFirmwareType(VOID)
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KeGetKernelParameter(IN PCWSTR ParameterName, BootInformation::GetKernelParameter(IN PCWSTR ParameterName,
OUT PCWSTR *Parameter) OUT PCWSTR *Parameter)
{ {
PCWSTR KernelParameters,Match, SearchStart; PCWSTR Match, SearchStart;
SIZE_T ParameterNameLength; SIZE_T ParameterNameLength;
/* Get the kernel parameters */
KernelParameters = KeInitializationBlock->KernelParameters;
/* Validate input parameters */ /* Validate input parameters */
if(!KernelParameters || !ParameterName || !Parameter) if(!ParameterName || !Parameter)
{ {
/* Invalid input parameters, return error */ /* Invalid input parameters, return error */
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
@@ -63,16 +71,16 @@ KeGetKernelParameter(IN PCWSTR ParameterName,
} }
/* Assume the requested parameter is not present in the kernel parameters */ /* Assume the requested parameter is not present in the kernel parameters */
*Parameter = NULL; *Parameter = nullptr;
/* Start searching from the beginning of the list */ /* Start searching from the beginning of the list */
SearchStart = KernelParameters; SearchStart = InitializationBlock->KernelParameters;
/* Search for the parameter name */ /* Search for the parameter name */
while((Match = RtlFindWideStringInsensitive(SearchStart, ParameterName))) while((Match = RtlFindWideStringInsensitive(SearchStart, ParameterName)))
{ {
/* Check if the match is at the start of the string or preceded by a space */ /* 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 */ /* Check the character after the match to avoid matching prefixes */
if(Match[ParameterNameLength] == L'\0' || if(Match[ParameterNameLength] == L'\0' ||
@@ -92,3 +100,50 @@ KeGetKernelParameter(IN PCWSTR ParameterName,
/* Parameter not found */ /* Parameter not found */
return STATUS_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();
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: System shutdown and kernel panic mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Halts the system. * Halts the system.
* *
@@ -18,14 +22,14 @@
*/ */
XTAPI XTAPI
VOID VOID
KeHaltSystem(VOID) Crash::HaltSystem(VOID)
{ {
/* Enter infinite loop */ /* Enter infinite loop */
for(;;) for(;;)
{ {
/* Halt system */ /* Halt system */
ArClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
ArHalt(); AR::CpuFunc::Halt();
} }
} }
@@ -41,9 +45,9 @@ KeHaltSystem(VOID)
*/ */
XTAPI XTAPI
VOID 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 XTAPI
VOID VOID
KePanicEx(IN ULONG Code, Crash::PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1, IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2, IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3, IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4) IN ULONG_PTR Parameter4)
{ {
KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code); 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);
} }

34
xtoskrnl/ke/data.cc Normal file
View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/data.cc
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* 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 */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: Deferred Procedure Call (DPC) support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Initializes Deferred Procedure Call (DPC) object. * Initializes Deferred Procedure Call (DPC) object.
* *
@@ -27,7 +31,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeDpc(IN PKDPC Dpc, Dpc::InitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext) IN PVOID DpcContext)
{ {
@@ -60,7 +64,7 @@ KeInitializeDpc(IN PKDPC Dpc,
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeThreadedDpc(IN PKDPC Dpc, Dpc::InitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine, IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext) IN PVOID DpcContext)
{ {
@@ -90,7 +94,7 @@ KeInitializeThreadedDpc(IN PKDPC Dpc,
*/ */
XTAPI XTAPI
VOID VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc, Dpc::SetTargetProcessor(IN PKDPC Dpc,
IN CCHAR Number) IN CCHAR Number)
{ {
Dpc->Number = MAXIMUM_PROCESSORS + Number; Dpc->Number = MAXIMUM_PROCESSORS + Number;
@@ -108,9 +112,9 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc,
*/ */
XTAPI XTAPI
VOID VOID
KeSignalCallDpcDone(IN PVOID SystemArgument) Dpc::SignalCallDone(IN PVOID SystemArgument)
{ {
RtlAtomicDecrement32(SystemArgument); RtlAtomicDecrement32((PLONG)SystemArgument);
} }
/** /**
@@ -125,7 +129,7 @@ KeSignalCallDpcDone(IN PVOID SystemArgument)
*/ */
XTAPI XTAPI
BOOLEAN BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument) Dpc::SignalCallSynchronize(IN PVOID SystemArgument)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
@@ -145,7 +149,9 @@ KeSignalCallDpcSynchronize(IN PVOID SystemArgument)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
KepRetireDpcList(IN PKPROCESSOR_CONTROL_BLOCK Prcb) Dpc::RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
} /* namespace */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/event.c * FILE: xtoskrnl/ke/event.cc
* DESCRIPTION: Kernel events support * DESCRIPTION: Kernel events support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Clears the signal state of the event. * Clears the signal state of the event.
* *
@@ -21,7 +25,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeClearEvent(IN PKEVENT Event) Event::ClearEvent(IN PKEVENT Event)
{ {
/* Clear event's signal state */ /* Clear event's signal state */
Event->Header.SignalState = FALSE; Event->Header.SignalState = FALSE;
@@ -45,7 +49,7 @@ KeClearEvent(IN PKEVENT Event)
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeEvent(OUT PKEVENT Event, Event::InitializeEvent(OUT PKEVENT Event,
IN KEVENT_TYPE EventType, IN KEVENT_TYPE EventType,
IN BOOLEAN InitialState) IN BOOLEAN InitialState)
{ {
@@ -75,7 +79,7 @@ KeInitializeEvent(OUT PKEVENT Event,
*/ */
XTAPI XTAPI
LONG LONG
KeSetEvent(IN PKEVENT Event, Event::SetEvent(IN PKEVENT Event,
IN KPRIORITY Increment, IN KPRIORITY Increment,
IN BOOLEAN Wait) IN BOOLEAN Wait)
{ {
@@ -83,3 +87,5 @@ KeSetEvent(IN PKEVENT Event,
return 0; return 0;
} }
} /* namespace */

482
xtoskrnl/ke/exports.cc Normal file
View File

@@ -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 <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* 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);
}

View File

@@ -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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* 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;

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: Kernel interrupts support for i686 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Sets new interrupt handler for the existing IDT entry. * Sets new interrupt handler for the existing IDT entry.
* *
@@ -24,7 +28,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeSetInterruptHandler(IN ULONG Vector, Irq::SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler) IN PVOID Handler)
{ {
PKPROCESSOR_BLOCK ProcessorBlock; PKPROCESSOR_BLOCK ProcessorBlock;
@@ -36,3 +40,17 @@ KeSetInterruptHandler(IN ULONG Vector,
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16); 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);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: CPU architecture specific kernel initialization
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* This routine initializes XT kernel. * This routine initializes XT kernel.
* *
@@ -18,7 +22,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeKernel(VOID) KernelInit::InitializeKernel(VOID)
{ {
XTSTATUS Status; XTSTATUS Status;
@@ -28,7 +32,7 @@ KepInitializeKernel(VOID)
{ {
/* Hardware layer initialization failed, kernel panic */ /* Hardware layer initialization failed, kernel panic */
DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
KePanic(0); Crash::Panic(0);
} }
} }
@@ -41,7 +45,7 @@ KepInitializeKernel(VOID)
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeMachine(VOID) KernelInit::InitializeMachine(VOID)
{ {
/* Re-enable IDE interrupts */ /* Re-enable IDE interrupts */
HlIoPortOutByte(0x376, 0); HlIoPortOutByte(0x376, 0);
@@ -66,7 +70,7 @@ KepInitializeMachine(VOID)
*/ */
XTAPI XTAPI
VOID VOID
KepStartKernel(VOID) KernelInit::StartKernel(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
ULONG_PTR PageDirectory[2]; ULONG_PTR PageDirectory[2];
@@ -74,8 +78,8 @@ KepStartKernel(VOID)
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
/* Get processor control block and current thread */ /* Get processor control block and current thread */
Prcb = KeGetCurrentProcessorControlBlock(); Prcb = Processor::GetCurrentProcessorControlBlock();
CurrentThread = KeGetCurrentThread(); CurrentThread = Processor::GetCurrentThread();
/* Get current process */ /* Get current process */
CurrentProcess = CurrentThread->ApcState.Process; CurrentProcess = CurrentThread->ApcState.Process;
@@ -84,23 +88,22 @@ KepStartKernel(VOID)
PoInitializeProcessorControlBlock(Prcb); PoInitializeProcessorControlBlock(Prcb);
/* Save processor state */ /* Save processor state */
KepSaveProcessorState(&Prcb->ProcessorState); Processor::SaveProcessorState(&Prcb->ProcessorState);
/* Lower to APC runlevel */ /* Lower to APC runlevel */
KeLowerRunLevel(APC_LEVEL); RunLevel::LowerRunLevel(APC_LEVEL);
/* Initialize XTOS kernel */ /* Initialize XTOS kernel */
KepInitializeKernel(); InitializeKernel();
/* Initialize Idle process */ /* Initialize Idle process */
RtlInitializeListHead(&KepProcessListHead);
PageDirectory[0] = 0; PageDirectory[0] = 0;
PageDirectory[1] = 0; PageDirectory[1] = 0;
KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
CurrentProcess->Quantum = MAXCHAR; CurrentProcess->Quantum = MAXCHAR;
/* Initialize Idle thread */ /* 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; CurrentThread->State = Running;
@@ -109,12 +112,12 @@ KepStartKernel(VOID)
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
/* Enter infinite loop */ /* Enter infinite loop */
DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n"); DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
for(;;); 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. * @return This routine does not return any value.
* *
@@ -122,22 +125,30 @@ KepStartKernel(VOID)
*/ */
XTAPI XTAPI
VOID 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 Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); 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" __asm__ volatile("mov %0, %%edx\n"
"xor %%ebp, %%ebp\n" "xor %%ebp, %%ebp\n"
"mov %%edx, %%esp\n" "mov %%edx, %%esp\n"
"sub %1, %%esp\n" "sub %1, %%esp\n"
"push %2\n" "push %2\n"
"jmp _KepStartKernel@0\n" "jmp *%3\n"
: :
: "m" (Stack), : "m" (Stack),
"i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
"i" (CR0_EM | CR0_MP | CR0_TS), "i" (CR0_EM | CR0_MP | CR0_TS),
"p" (KepStartKernel) "r" (StartKernel)
: "edx", "ebp", "esp", "memory"); : "edx", "ebp", "esp", "memory");
} }
} /* namespace */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: I686 thread manipulation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Initializes CPU architecture dependent context of a thread. * Initializes CPU architecture dependent context of a thread.
* *
@@ -33,7 +37,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeThreadContext(IN PKTHREAD Thread, KThread::InitializeThreadContext(IN PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine, IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext, IN PVOID StartContext,
@@ -43,7 +47,7 @@ KepInitializeThreadContext(IN PKTHREAD Thread,
PFX_SAVE_FORMAT FxSaveFormat; PFX_SAVE_FORMAT FxSaveFormat;
/* Set initial thread frame */ /* 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 */ /* Fill floating point save area with zeroes */
RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA)); RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA));
@@ -114,3 +118,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread,
/* Set thread stack */ /* Set thread stack */
Thread->KernelStack = &ThreadFrame->SwitchFrame; Thread->KernelStack = &ThreadFrame->SwitchFrame;
} }
} /* namespace */

View File

@@ -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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* 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);
}

150
xtoskrnl/ke/i686/proc.cc Normal file
View File

@@ -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 <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* 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);
}

View File

@@ -1,14 +1,25 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: XT kernel process manipulation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
XTAPI
PEPROCESS
KProcess::GetInitialProcess(VOID)
{
return &InitialProcess;
}
/** /**
* Initializes the process. * Initializes the process.
* *
@@ -33,7 +44,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeProcess(IN OUT PKPROCESS Process, KProcess::InitializeProcess(IN OUT PKPROCESS Process,
IN KPRIORITY Priority, IN KPRIORITY Priority,
IN KAFFINITY Affinity, IN KAFFINITY Affinity,
IN PULONG_PTR DirectoryTable, IN PULONG_PTR DirectoryTable,
@@ -67,3 +78,19 @@ KeInitializeProcess(IN OUT PKPROCESS Process,
/* Set initial process state */ /* Set initial process state */
Process->State = ProcessInMemory; 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);
}

View File

@@ -1,14 +1,17 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/krnlinit.c * FILE: xtoskrnl/ke/krnlinit.cc
* DESCRIPTION: XT kernel initialization * DESCRIPTION: XT kernel initialization
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Use routines from Kernel Library */
using namespace KE;
/** /**
* This routine starts up the XT kernel. It is called by boot loader. * This routine starts up the XT kernel. It is called by boot loader.
* *
@@ -23,31 +26,31 @@ XTAPI
VOID VOID
KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
{ {
/* Save the kernel initialization block */
KeInitializationBlock = Parameters;
/* Verify kernel and boot loader compatibility */ /* Verify kernel and boot loader compatibility */
if(KeInitializationBlock->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) || if(Parameters->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) ||
KeInitializationBlock->BlockVersion != INITIALIZATION_BLOCK_VERSION || Parameters->BlockVersion != INITIALIZATION_BLOCK_VERSION ||
KeInitializationBlock->ProtocolVersion != BOOT_PROTOCOL_VERSION) Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION)
{ {
/* Kernel and boot loader version mismatch */ /* 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 */ /* 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 */ /* 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); DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME);
} }
/* Initialize boot CPU */ /* Initialize boot CPU */
ArInitializeProcessor(NULL); AR::ProcSup::InitializeProcessor(NULL);
/* Initialize system resources */ /* Initialize system resources */
KepInitializeSystemResources(); SystemResources::InitializeResources();
/* Check if debugging enabled */ /* Check if debugging enabled */
if(DEBUG) if(DEBUG)
@@ -63,11 +66,11 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION); XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION);
/* Architecture specific kernel initialization */ /* Architecture specific kernel initialization */
KepInitializeMachine(); KernelInit::InitializeMachine();
/* Raise to HIGH runlevel */ /* Raise to HIGH runlevel */
KeRaiseRunLevel(HIGH_LEVEL); RunLevel::RaiseRunLevel(HIGH_LEVEL);
/* Switch the boot stack and transfer control to the KepStartKernel() routine */ /* Switch the boot stack and transfer control to the KepStartKernel() routine */
KepSwitchBootStack(); KernelInit::SwitchBootStack();
} }

View File

@@ -1,14 +1,45 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: XT kernel thread manipulation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* 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. * Initializes the thread.
* *
@@ -42,7 +73,7 @@
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KeInitializeThread(IN PKPROCESS Process, KThread::InitializeThread(IN PKPROCESS Process,
IN OUT PKTHREAD Thread, IN OUT PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine, IN PKSTART_ROUTINE StartRoutine,
@@ -50,7 +81,7 @@ KeInitializeThread(IN PKPROCESS Process,
IN PCONTEXT Context, IN PCONTEXT Context,
IN PVOID EnvironmentBlock, IN PVOID EnvironmentBlock,
IN PVOID Stack, IN PVOID Stack,
IN BOOLEAN StartThread) IN BOOLEAN RunThread)
{ {
PKWAIT_BLOCK TimerWaitBlock; PKWAIT_BLOCK TimerWaitBlock;
BOOLEAN Allocation; BOOLEAN Allocation;
@@ -86,10 +117,7 @@ KeInitializeThread(IN PKPROCESS Process,
Thread->AdjustReason = AdjustNone; Thread->AdjustReason = AdjustNone;
/* Initialize thread lock */ /* Initialize thread lock */
KeInitializeSpinLock(&Thread->ThreadLock); SpinLock::InitializeSpinLock(&Thread->ThreadLock);
/* Set thread service table */
Thread->ServiceTable = KeServiceDescriptorTable;
/* Initialize thread APC */ /* Initialize thread APC */
Thread->ApcStatePointer[0] = &Thread->ApcState; Thread->ApcStatePointer[0] = &Thread->ApcState;
@@ -103,17 +131,17 @@ KeInitializeThread(IN PKPROCESS Process,
RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
/* Initialize APC queue lock */ /* Initialize APC queue lock */
KeInitializeSpinLock(&Thread->ApcQueueLock); SpinLock::InitializeSpinLock(&Thread->ApcQueueLock);
/* Initialize kernel-mode suspend APC */ /* Initialize kernel-mode suspend APC */
KeInitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, KepSuspendNop, Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop,
KepSuspendRundown, KepSuspendThread, KernelMode, NULL); SuspendRundown, SuspendThread, KernelMode, NULL);
/* Initialize suspend semaphore */ /* Initialize suspend semaphore */
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2); Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
/* Initialize the builtin timer */ /* Initialize the builtin timer */
KeInitializeTimer(&Thread->Timer, NotificationTimer); Timer::InitializeTimer(&Thread->Timer, NotificationTimer);
TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK]; TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK];
TimerWaitBlock->Object = &Thread->Timer; TimerWaitBlock->Object = &Thread->Timer;
TimerWaitBlock->WaitKey = STATUS_TIMEOUT; TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
@@ -122,7 +150,7 @@ KeInitializeThread(IN PKPROCESS Process,
TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead; TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead;
/* Initialize Thread Environment Block*/ /* Initialize Thread Environment Block*/
Thread->EnvironmentBlock = EnvironmentBlock; Thread->EnvironmentBlock = (PTHREAD_ENVIRONMENT_BLOCK)EnvironmentBlock;
/* Make sure there is a valid stack available */ /* Make sure there is a valid stack available */
if(!Stack) if(!Stack)
@@ -141,12 +169,12 @@ KeInitializeThread(IN PKPROCESS Process,
Thread->InitialStack = Stack; Thread->InitialStack = Stack;
Thread->StackBase = Stack; Thread->StackBase = Stack;
Thread->StackLimit = Stack - KERNEL_STACK_SIZE; Thread->StackLimit = (PVOID)((ULONG_PTR)Stack - KERNEL_STACK_SIZE);
__try __try
{ {
/* Initialize thread context */ /* Initialize thread context */
KepInitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context); InitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context);
} }
__except(EXCEPTION_EXECUTE_HANDLER) __except(EXCEPTION_EXECUTE_HANDLER)
{ {
@@ -167,10 +195,10 @@ KeInitializeThread(IN PKPROCESS Process,
Thread->State = Initialized; Thread->State = Initialized;
/* Check if thread should be started */ /* Check if thread should be started */
if(StartThread) if(RunThread)
{ {
/* Start thread */ /* Start thread */
KeStartThread(Thread); StartThread(Thread);
} }
/* Return success */ /* Return success */
@@ -189,31 +217,11 @@ KeInitializeThread(IN PKPROCESS Process,
*/ */
XTAPI XTAPI
VOID VOID
KeStartThread(IN PKTHREAD Thread) KThread::StartThread(IN PKTHREAD Thread)
{ {
UNIMPLEMENTED; 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. * Suspend APC-built thread NOP routine. It takes no actions.
* *
@@ -238,7 +246,7 @@ KepExitDispatcher(IN KRUNLEVEL OldRunLevel)
*/ */
XTAPI XTAPI
VOID VOID
KepSuspendNop(IN PKAPC Apc, KThread::SuspendNop(IN PKAPC Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine, IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext, IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1, IN OUT PVOID *SystemArgument1,
@@ -259,7 +267,7 @@ KepSuspendNop(IN PKAPC Apc,
*/ */
XTAPI XTAPI
VOID VOID
KepSuspendRundown(IN PKAPC Apc) KThread::SuspendRundown(IN PKAPC Apc)
{ {
/* No action here */ /* No action here */
} }
@@ -282,9 +290,30 @@ KepSuspendRundown(IN PKAPC Apc)
*/ */
XTAPI XTAPI
VOID VOID
KepSuspendThread(IN PVOID NormalContext, KThread::SuspendThread(IN PVOID NormalContext,
IN PVOID SystemArgument1, IN PVOID SystemArgument1,
IN PVOID SystemArgument2) IN PVOID SystemArgument2)
{ {
UNIMPLEMENTED; 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);
}

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Checks whether handled UBSAN error should be reported. * Checks whether handled UBSAN error should be reported.
* *
@@ -21,10 +25,10 @@
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location) KUbsan::CheckReport(PKUBSAN_SOURCE_LOCATION Location)
{ {
/* Make sure, this error should be reported */ /* Make sure, this error should be reported */
return !KepUbsanActiveFrame; return (BOOLEAN)!ActiveFrame;
} }
/** /**
@@ -42,11 +46,11 @@ KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location)
*/ */
XTCDECL XTCDECL
VOID VOID
KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location, KUbsan::EnterFrame(PKUBSAN_SOURCE_LOCATION Location,
PCCHAR Reason) PCCHAR Reason)
{ {
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepUbsanActiveFrame = TRUE; ActiveFrame = TRUE;
/* Print generic error message to debug console */ /* Print generic error message to debug console */
DebugPrint(L"UBSAN: Undefined behavior (%s) in %s:%d:%d\n", DebugPrint(L"UBSAN: Undefined behavior (%s) in %s:%d:%d\n",
@@ -68,7 +72,7 @@ KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location,
*/ */
XTCDECL XTCDECL
LONGLONG LONGLONG
KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, KUbsan::GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
PVOID Value) PVOID Value)
{ {
ULONG BitWidth, ExtraBits; ULONG BitWidth, ExtraBits;
@@ -102,7 +106,7 @@ KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
*/ */
XTCDECL XTCDECL
PCCHAR PCCHAR
KepGetUbsanTypeKind(UCHAR TypeCheckKind) KUbsan::GetTypeKind(UCHAR TypeCheckKind)
{ {
/* Get type kind name */ /* Get type kind name */
switch(TypeCheckKind) switch(TypeCheckKind)
@@ -147,7 +151,7 @@ KepGetUbsanTypeKind(UCHAR TypeCheckKind)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type, KUbsan::GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
PVOID Value) PVOID Value)
{ {
ULONG BitWidth; ULONG BitWidth;
@@ -184,22 +188,22 @@ KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data, KUbsan::HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
PVOID Lhs, PVOID Lhs,
PVOID Rhs) PVOID Rhs)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Division-Overflow"); EnterFrame(&Data->Location, "Division-Overflow");
/* Check if signed type, which value is -1 */ /* 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 */ /* 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); 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 */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -232,25 +236,25 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data, KUbsan::HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
ULONG_PTR Lhs, ULONG_PTR Lhs,
ULONG_PTR Rhs) ULONG_PTR Rhs)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); EnterFrame(&Data->Location, "Float-Cast-Overflow");
/* Print error message to debug console */ /* 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); DebugPrint(L"Value of type %s is outside the range of type %s\n", Data->LhsType->TypeName, Data->RhsType->TypeName);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -268,25 +272,25 @@ KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data, KUbsan::HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer) ULONG_PTR Pointer)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow"); EnterFrame(&Data->Location, "Float-Cast-Overflow");
/* Print error message to debug console */ /* Print error message to debug console */
DebugPrint(L"UBSAN: Indirect function call through %P address of a wrong type %s\n", DebugPrint(L"UBSAN: Indirect function call through %P address of a wrong type %s\n",
(PVOID)Pointer, Data->Type->TypeName); (PVOID)Pointer, Data->Type->TypeName);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -307,25 +311,25 @@ KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data, KUbsan::HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR Lhs, ULONG_PTR Lhs,
ULONG_PTR Rhs) ULONG_PTR Rhs)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Integer-Overflow"); EnterFrame(&Data->Location, "Integer-Overflow");
/* Print error message to debug console */ /* 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); DebugPrint(L"UBSAN: The result of an arithmetic operation cannot be represented in type %s\n", Data->Type->TypeName);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -340,17 +344,17 @@ KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data) KUbsan::HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Invalid-Builtin"); EnterFrame(&Data->Location, "Invalid-Builtin");
/* Check kind of UBSAN error */ /* Check kind of UBSAN error */
if(Data->Kind == 0 || Data->Kind == 1) if(Data->Kind == 0 || Data->Kind == 1)
@@ -365,7 +369,7 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
} }
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -383,25 +387,25 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data, KUbsan::HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer) ULONG_PTR Pointer)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Misaligned-Access"); EnterFrame(&Data->Location, "Misaligned-Access");
/* Print error message to debug console */ /* Print error message to debug console */
DebugPrint(L"UBSAN: %s misaligned address %p for type %s which requires %ld byte alignment\n", 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 */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -419,24 +423,24 @@ KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data, KUbsan::HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR OldValue) ULONG_PTR OldValue)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Negate-Overflow"); EnterFrame(&Data->Location, "Negate-Overflow");
/* Print error message to debug console */ /* Print error message to debug console */
DebugPrint(L"UBSAN: Negation of %lu cannot be represented in type %s\n", OldValue, Data->Type->TypeName); DebugPrint(L"UBSAN: Negation of %lu cannot be represented in type %s\n", OldValue, Data->Type->TypeName);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
@@ -455,23 +459,23 @@ KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data) KUbsan::HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "NULL-Pointer-Dereference"); EnterFrame(&Data->Location, "NULL-Pointer-Dereference");
/* Print error message to debug console */ /* 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 */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -489,25 +493,25 @@ KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, KUbsan::HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer) ULONG_PTR Pointer)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Object-Size-Mismatch"); EnterFrame(&Data->Location, "Object-Size-Mismatch");
/* Print error message to debug console */ /* Print error message to debug console */
DebugPrint(L"UBSAN: %s address %p with insufficient space for an object of type %s\n", 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 */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -525,24 +529,24 @@ KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data, KUbsan::HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
ULONG_PTR Index) ULONG_PTR Index)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* 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 */ /* Print error message to debug console */
DebugPrint(L"UBSAN: index is out of range for type %s", Data->ArrayType->TypeName); DebugPrint(L"UBSAN: index is out of range for type %s", Data->ArrayType->TypeName);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -563,26 +567,26 @@ KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data, KUbsan::HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR Lhs, ULONG_PTR Lhs,
ULONG_PTR Rhs) ULONG_PTR Rhs)
{ {
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Pointer-Overflow"); EnterFrame(&Data->Location, "Pointer-Overflow");
/* Print error message to debug console */ /* Print error message to debug console */
DebugPrint(L"UBSAN: Pointer operation %s %p to %p\n", DebugPrint(L"UBSAN: Pointer operation %s %p to %p\n",
Lhs > Rhs ? "overflowed" : "underflowed", (PVOID)Lhs, (PVOID)Rhs); Lhs > Rhs ? "overflowed" : "underflowed", (PVOID)Lhs, (PVOID)Rhs);
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
@@ -604,52 +608,52 @@ KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data, KUbsan::HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
ULONG_PTR Lhs, ULONG_PTR Lhs,
ULONG_PTR Rhs) ULONG_PTR Rhs)
{ {
ULONG LhsBitWidth; ULONG LhsBitWidth;
/* Check if this error was already reported */ /* Check if this error was already reported */
if(!KepCheckUbsanReport(&Data->Location)) if(!CheckReport(&Data->Location))
{ {
/* Don't report twice */ /* Don't report twice */
return; return;
} }
/* Enter UBSAN frame */ /* Enter UBSAN frame */
KepEnterUbsanFrame(&Data->Location, "Shift-Out-Of-Bounds"); EnterFrame(&Data->Location, "Shift-Out-Of-Bounds");
/* Calculate Lhs bit width */ /* Calculate Lhs bit width */
LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1); LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1);
/* Check a type of out of bounds error */ /* 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 */ /* 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 */ /* 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 */ /* 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", 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 else
{ {
/* Left shift too large, print error message to debug console */ /* 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", 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); Data->LhsType->TypeName);
} }
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepLeaveUbsanFrame(); LeaveFrame();
} }
/** /**
@@ -667,24 +671,24 @@ KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data, KUbsan::HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer) ULONG_PTR Pointer)
{ {
/* Check the type of mismatch */ /* Check the type of mismatch */
if(!Pointer) if(!Pointer)
{ {
/* Handle NULL pointer dereference */ /* 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 */ /* Handle misaligned access */
KepHandleUbsanMisalignedAccess(Data, Pointer); HandleMisalignedAccess(Data, Pointer);
} }
else else
{ {
/* Handle object size mismatch */ /* Handle object size mismatch */
KepHandleUbsanObjectSizeMismatch(Data, Pointer); HandleObjectSizeMismatch(Data, Pointer);
} }
} }
@@ -697,12 +701,17 @@ KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
*/ */
XTCDECL XTCDECL
VOID VOID
KepLeaveUbsanFrame() KUbsan::LeaveFrame()
{ {
/* Leave UBSAN frame */ /* Leave UBSAN frame */
KepUbsanActiveFrame = FALSE; ActiveFrame = FALSE;
} }
} /* namespace */
/** /**
* Handles the addition overflow error. This is internal routine implementing ABI defined by CLANG UBSAN. * 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 * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113
*/ */
XTCLINK
XTCDECL XTCDECL
VOID VOID
__ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data, __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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN arithmetic overflow handler */ /* 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 * @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113
*/ */
XTCLINK
XTCDECL XTCDECL
VOID VOID
__ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data, __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) IN PVOID Rhs)
{ {
/* Call UBSAN division overflow handler */ /* 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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN float cast overflow handler */ /* 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) IN ULONG_PTR Pointer)
{ {
/* Call UBSAN function type mismatch handler */ /* 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) __ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data)
{ {
/* Call UBSAN invalid builtin handler */ /* 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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN arithmetic overflow handler */ /* 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) IN ULONG_PTR OldValue)
{ {
/* Call UBSAN negate overflow handler */ /* 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) IN ULONG_PTR Index)
{ {
/* Call UBSAN out of bounds handler */ /* 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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN pointer overflow handler */ /* 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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN out of bounds handler */ /* 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) IN ULONG_PTR Rhs)
{ {
/* Call UBSAN arithmetic overflow handler */ /* 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) IN ULONG_PTR Pointer)
{ {
/* Call UBSAN type mismatch handler */ /* 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; MismatchData.TypeCheckKind = Data->TypeCheckKind;
/* Call UBSAN type mismatch handler */ /* Call UBSAN type mismatch handler */
KepHandleUbsanTypeMismatch(&MismatchData, Pointer); KE::KUbsan::HandleTypeMismatch(&MismatchData, Pointer);
} }

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/runlevel.c * FILE: xtoskrnl/ke/runlevel.cc
* DESCRIPTION: Running Level management support * DESCRIPTION: Running Level management support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Gets the current running level of the current processor. * Gets the current running level of the current processor.
* *
@@ -18,7 +22,7 @@
*/ */
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeGetCurrentRunLevel(VOID) RunLevel::GetCurrentRunLevel(VOID)
{ {
return HlGetRunLevel(); return HlGetRunLevel();
} }
@@ -35,7 +39,7 @@ KeGetCurrentRunLevel(VOID)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
KeLowerRunLevel(IN KRUNLEVEL RunLevel) RunLevel::LowerRunLevel(IN KRUNLEVEL RunLevel)
{ {
KRUNLEVEL OldRunLevel; KRUNLEVEL OldRunLevel;
@@ -62,7 +66,7 @@ KeLowerRunLevel(IN KRUNLEVEL RunLevel)
*/ */
XTFASTCALL XTFASTCALL
KRUNLEVEL KRUNLEVEL
KeRaiseRunLevel(IN KRUNLEVEL RunLevel) RunLevel::RaiseRunLevel(IN KRUNLEVEL RunLevel)
{ {
KRUNLEVEL OldRunLevel; KRUNLEVEL OldRunLevel;
@@ -79,3 +83,33 @@ KeRaiseRunLevel(IN KRUNLEVEL RunLevel)
/* Return old run level */ /* Return old run level */
return OldRunLevel; 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);
}

View File

@@ -1,16 +1,19 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/semphore.c * FILE: xtoskrnl/ke/semphore.cc
* DESCRIPTION: Semaphores support * DESCRIPTION: Semaphores support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
namespace KE
{
/** /**
* initializes a kernel semaphore object. * Initializes a kernel semaphore object.
* *
* @param Semaphore * @param Semaphore
* Supplies a pointer to a semaphore object. * Supplies a pointer to a semaphore object.
@@ -27,7 +30,7 @@
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, Semaphore::InitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count, IN LONG Count,
IN LONG Limit) IN LONG Limit)
{ {
@@ -52,7 +55,7 @@ KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
*/ */
XTAPI XTAPI
LONG LONG
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore) Semaphore::ReadState(IN PKSEMAPHORE Semaphore)
{ {
/* Return semaphore's signal state */ /* Return semaphore's signal state */
return Semaphore->Header.SignalState; return Semaphore->Header.SignalState;
@@ -79,7 +82,7 @@ KeReadSemaphoreState(IN PKSEMAPHORE Semaphore)
*/ */
XTAPI XTAPI
LONG LONG
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, Semaphore::ReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN KPRIORITY Increment, IN KPRIORITY Increment,
IN LONG Adjustment, IN LONG Adjustment,
IN BOOLEAN Wait) IN BOOLEAN Wait)
@@ -87,3 +90,5 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
UNIMPLEMENTED; UNIMPLEMENTED;
return 0; return 0;
} }
} /* namespace */

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/spinlock.c * FILE: xtoskrnl/ke/spinlock.cc
* DESCRIPTION: Spinlocks support * DESCRIPTION: Spinlocks support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Acquires a specified queued spinlock. * Acquires a specified queued spinlock.
* *
@@ -21,10 +25,10 @@
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) SpinLock::AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{ {
/* Acquire the queued spinlock */ /* 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 XTFASTCALL
VOID VOID
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock) SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
{ {
/* Try to acquire the lock */ /* Try to acquire the lock */
while(RtlAtomicBitTestAndSet((PLONG)SpinLock, 0)) while(RtlAtomicBitTestAndSet((PLONG)SpinLock, 0))
@@ -68,7 +72,7 @@ KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock) SpinLock::InitializeSpinLock(IN PKSPIN_LOCK SpinLock)
{ {
/* Zero initialize spinlock */ /* Zero initialize spinlock */
*SpinLock = 0; *SpinLock = 0;
@@ -86,10 +90,10 @@ KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel) SpinLock::ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{ {
/* Clear the lock */ /* 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 XTFASTCALL
VOID VOID
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock) SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
{ {
/* Clear the lock */ /* Clear the lock */
RtlAtomicAnd32((PLONG)SpinLock, 0); RtlAtomicAnd32((PLONG)SpinLock, 0);
@@ -112,3 +116,5 @@ KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
/* Add an explicit memory barrier */ /* Add an explicit memory barrier */
ArReadWriteBarrier(); ArReadWriteBarrier();
} }
} /* namespace */

View File

@@ -1,15 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * 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 <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Looks for an unacquired system resource of the specified type and acquires it. * Looks for an unacquired system resource of the specified type and acquires it.
* *
@@ -25,59 +28,11 @@
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{ {
/* Get system resource and acquire an ownership */ /* Get system resource and acquire an ownership */
return KepGetSystemResource(ResourceType, TRUE, ResourceHeader); return GetSystemResource(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();
} }
/** /**
@@ -98,7 +53,7 @@ KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
IN BOOLEAN ResourceLock, IN BOOLEAN ResourceLock,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{ {
@@ -111,15 +66,15 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
/* Check if interrupts are enabled */ /* Check if interrupts are enabled */
Interrupts = ArInterruptsEnabled(); Interrupts = AR::CpuFunc::InterruptsEnabled();
/* Disable interrupts and acquire a spinlock */ /* Disable interrupts and acquire a spinlock */
ArClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KeAcquireSpinLock(&KepSystemResourcesLock); SpinLock::AcquireSpinLock(&ResourcesLock);
/* Iterate through system resources list */ /* Iterate through system resources list */
ListEntry = KepSystemResourcesListHead.Flink; ListEntry = ResourcesListHead.Flink;
while(ListEntry != &KepSystemResourcesListHead) while(ListEntry != &ResourcesListHead)
{ {
/* Get resource header */ /* Get resource header */
Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
@@ -151,19 +106,19 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
} }
/* Check if resource was found */ /* Check if resource was found */
if(ListEntry == &KepSystemResourcesListHead) if(ListEntry == &ResourcesListHead)
{ {
/* Resource not found, return NULL */ /* Resource not found, return NULL */
Resource = NULL; Resource = nullptr;
Status = STATUS_NOT_FOUND; Status = STATUS_NOT_FOUND;
} }
/* Release spinlock and re-enable interrupts if necessary */ /* Release spinlock and re-enable interrupts if necessary */
KeReleaseSpinLock(&KepSystemResourcesLock); SpinLock::ReleaseSpinLock(&ResourcesLock);
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
ArSetInterruptFlag(); AR::CpuFunc::SetInterruptFlag();
} }
/* Return resource header and status code */ /* Return resource header and status code */
@@ -171,6 +126,28 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
return Status; 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. * Initializes system resource management.
* *
@@ -180,22 +157,22 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeSystemResources(VOID) SystemResources::InitializeResources(VOID)
{ {
PSYSTEM_RESOURCE_HEADER ResourceHeader; PSYSTEM_RESOURCE_HEADER ResourceHeader;
PLIST_ENTRY ListEntry, NextListEntry; PLIST_ENTRY ListEntry, NextListEntry;
ULONG ResourceSize; ULONG ResourceSize;
/* Initialize system resources spin lock and resource list */ /* Initialize system resources spin lock and resource list */
KeInitializeSpinLock(&KepSystemResourcesLock); SpinLock::InitializeSpinLock(&ResourcesLock);
RtlInitializeListHead(&KepSystemResourcesListHead); RtlInitializeListHead(&ResourcesListHead);
/* Make sure there are some system resources available */ /* Make sure there are some system resources available */
if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead)) if(!RtlListEmpty(BootInformation::GetSystemResources()))
{ {
/* Iterate through system resources list */ /* Iterate through system resources list */
ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink; ListEntry = BootInformation::GetSystemResources()->Flink;
while(ListEntry != &KeInitializationBlock->SystemResourcesListHead) while(ListEntry != BootInformation::GetSystemResources())
{ {
/* Get resource header and next list entry */ /* Get resource header and next list entry */
ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); 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 */ /* Move valid resource to the internal kernel list of system resources */
RtlRemoveEntryList(&ResourceHeader->ListEntry); RtlRemoveEntryList(&ResourceHeader->ListEntry);
RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry); RtlInsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry);
} }
/* Go to the next list entry */ /* 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 */

View File

@@ -1,14 +1,17 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/timer.c * FILE: xtoskrnl/ke/timer.cc
* DESCRIPTION: Kernel timer object support * DESCRIPTION: Kernel timer object support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
namespace KE
{
/** /**
* Cancels the timer. * Cancels the timer.
* *
@@ -21,7 +24,7 @@
*/ */
XTAPI XTAPI
BOOLEAN BOOLEAN
KeCancelTimer(IN PKTIMER Timer) Timer::CancelTimer(IN PKTIMER Timer)
{ {
BOOLEAN Result; BOOLEAN Result;
KRUNLEVEL RunLevel; KRUNLEVEL RunLevel;
@@ -31,19 +34,19 @@ KeCancelTimer(IN PKTIMER Timer)
/* Raise run level and acquire dispatcher lock */ /* Raise run level and acquire dispatcher lock */
RunLevel = KeRaiseRunLevel(SYNC_LEVEL); RunLevel = KeRaiseRunLevel(SYNC_LEVEL);
KeAcquireQueuedSpinLock(DispatcherLock); SpinLock::AcquireQueuedSpinLock(DispatcherLock);
/* Check timer status */ /* Check timer status */
if(Timer->Header.Inserted) if(Timer->Header.Inserted)
{ {
/* Remove the timer from the list */ /* Remove the timer from the list */
KepRemoveTimer(Timer); RemoveTimer(Timer);
Result = TRUE; Result = TRUE;
} }
/* Release dispatcher lock and process the deferred ready list */ /* Release dispatcher lock and process the deferred ready list */
KeReleaseQueuedSpinLock(DispatcherLock); SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
KepExitDispatcher(RunLevel); KThread::ExitDispatcher(RunLevel);
/* Return result */ /* Return result */
return Result; return Result;
@@ -61,7 +64,7 @@ KeCancelTimer(IN PKTIMER Timer)
*/ */
XTAPI XTAPI
VOID VOID
KeClearTimer(IN PKTIMER Timer) Timer::ClearTimer(IN PKTIMER Timer)
{ {
/* Clear signal state */ /* Clear signal state */
Timer->Header.SignalState = 0; Timer->Header.SignalState = 0;
@@ -79,7 +82,7 @@ KeClearTimer(IN PKTIMER Timer)
*/ */
XTAPI XTAPI
BOOLEAN BOOLEAN
KeGetTimerState(IN PKTIMER Timer) Timer::GetState(IN PKTIMER Timer)
{ {
/* Return timer state */ /* Return timer state */
return (BOOLEAN)Timer->Header.SignalState; return (BOOLEAN)Timer->Header.SignalState;
@@ -100,11 +103,11 @@ KeGetTimerState(IN PKTIMER Timer)
*/ */
XTAPI XTAPI
VOID VOID
KeInitializeTimer(OUT PKTIMER Timer, Timer::InitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type) IN KTIMER_TYPE Type)
{ {
/* Initialize the header */ /* Initialize the header */
Timer->Header.Type = TimerNotificationObject + Type; Timer->Header.Type = TimerNotificationObject + (UCHAR)Type;
Timer->Header.Inserted = 0; Timer->Header.Inserted = 0;
Timer->Header.SignalState = 0; Timer->Header.SignalState = 0;
@@ -129,7 +132,7 @@ KeInitializeTimer(OUT PKTIMER Timer,
*/ */
XTAPI XTAPI
ULONGLONG ULONGLONG
KeQueryTimer(IN PKTIMER Timer) Timer::QueryTimer(IN PKTIMER Timer)
{ {
KRUNLEVEL RunLevel; KRUNLEVEL RunLevel;
ULONGLONG DueTime; ULONGLONG DueTime;
@@ -139,7 +142,7 @@ KeQueryTimer(IN PKTIMER Timer)
/* Raise run level and acquire dispatcher lock */ /* Raise run level and acquire dispatcher lock */
RunLevel = KeRaiseRunLevel(SYNC_LEVEL); RunLevel = KeRaiseRunLevel(SYNC_LEVEL);
KeAcquireQueuedSpinLock(DispatcherLock); SpinLock::AcquireQueuedSpinLock(DispatcherLock);
/* Check timer status */ /* Check timer status */
if(Timer->Header.Inserted) if(Timer->Header.Inserted)
@@ -149,8 +152,8 @@ KeQueryTimer(IN PKTIMER Timer)
} }
/* Release dispatcher lock and process the deferred ready list */ /* Release dispatcher lock and process the deferred ready list */
KeReleaseQueuedSpinLock(DispatcherLock); SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
KepExitDispatcher(RunLevel); KThread::ExitDispatcher(RunLevel);
/* Return timer's due time */ /* Return timer's due time */
return DueTime; return DueTime;
@@ -177,7 +180,7 @@ KeQueryTimer(IN PKTIMER Timer)
*/ */
XTAPI XTAPI
VOID VOID
KeSetTimer(IN PKTIMER Timer, Timer::SetTimer(IN PKTIMER Timer,
IN LARGE_INTEGER DueTime, IN LARGE_INTEGER DueTime,
IN LONG Period, IN LONG Period,
IN PKDPC Dpc) IN PKDPC Dpc)
@@ -197,9 +200,11 @@ KeSetTimer(IN PKTIMER Timer,
*/ */
XTAPI XTAPI
VOID VOID
KepRemoveTimer(IN OUT PKTIMER Timer) Timer::RemoveTimer(IN OUT PKTIMER Timer)
{ {
/* Remove the timer from the list */ /* Remove the timer from the list */
Timer->Header.Inserted = FALSE; Timer->Header.Inserted = FALSE;
RtlRemoveEntryList(&Timer->TimerListEntry); RtlRemoveEntryList(&Timer->TimerListEntry);
} }
} /* namespace */

View File

@@ -50,8 +50,8 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount,
} }
/* Scan memory descriptors provided by the boot loader */ /* Scan memory descriptors provided by the boot loader */
ListEntry = KeInitializationBlock->MemoryDescriptorListHead.Flink; ListEntry = KeGetInitializationBlock()->MemoryDescriptorListHead.Flink;
while(ListEntry != &KeInitializationBlock->MemoryDescriptorListHead) while(ListEntry != &KeGetInitializationBlock()->MemoryDescriptorListHead)
{ {
Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry); Descriptor = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_DESCRIPTOR, ListEntry);
@@ -77,7 +77,7 @@ MmAllocateHardwareMemory(IN PFN_NUMBER PageCount,
} }
/* Make sure we found a descriptor */ /* Make sure we found a descriptor */
if(ListEntry == &KeInitializationBlock->MemoryDescriptorListHead) if(ListEntry == &KeGetInitializationBlock()->MemoryDescriptorListHead)
{ {
/* Descriptor not found, return error */ /* Descriptor not found, return error */
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;

View File

@@ -54,8 +54,8 @@ MmpScanMemoryDescriptors(VOID)
FreePages = 0; FreePages = 0;
/* Iterate through memory mappings provided by the boot loader */ /* Iterate through memory mappings provided by the boot loader */
MemoryMappings = KeInitializationBlock->MemoryDescriptorListHead.Flink; MemoryMappings = KeGetInitializationBlock()->MemoryDescriptorListHead.Flink;
while(MemoryMappings != &KeInitializationBlock->MemoryDescriptorListHead) while(MemoryMappings != &KeGetInitializationBlock()->MemoryDescriptorListHead)
{ {
/* Get memory descriptor */ /* Get memory descriptor */
MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry); MemoryDescriptor = CONTAIN_RECORD(MemoryMappings, LOADER_MEMORY_DESCRIPTOR, ListEntry);