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,8 +28,8 @@
*/ */
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,14 +46,14 @@
*/ */
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,
IN PKRUNDOWN_ROUTINE RundownRoutine, IN PKRUNDOWN_ROUTINE RundownRoutine,
IN PKNORMAL_ROUTINE NormalRoutine, IN PKNORMAL_ROUTINE NormalRoutine,
IN KPROCESSOR_MODE ApcMode, IN KPROCESSOR_MODE ApcMode,
IN PVOID Context) IN PVOID Context)
{ {
/* Set APC type and thread */ /* Set APC type and thread */
Apc->Type = ApcObject; Apc->Type = ApcObject;
@@ -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,9 +31,9 @@
*/ */
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)
{ {
/* Initialize DPC */ /* Initialize DPC */
Dpc->Type = DpcObject; Dpc->Type = DpcObject;
@@ -60,9 +64,9 @@ 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)
{ {
/* Initialize threaded DPC */ /* Initialize threaded DPC */
Dpc->Type = ThreadedDpcObject; Dpc->Type = ThreadedDpcObject;
@@ -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,9 +49,9 @@ 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)
{ {
/* Initialize event dispatcher header */ /* Initialize event dispatcher header */
Event->Header.Type = EventType; Event->Header.Type = EventType;
@@ -75,11 +79,13 @@ 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)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
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,17 +37,17 @@
*/ */
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,
IN PCONTEXT ContextRecord) IN PCONTEXT ContextRecord)
{ {
PKTHREAD_INIT_FRAME ThreadFrame; PKTHREAD_INIT_FRAME ThreadFrame;
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,11 +44,11 @@
*/ */
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,
IN BOOLEAN Alignment) IN BOOLEAN Alignment)
{ {
/* Initialize process dispatcher header */ /* Initialize process dispatcher header */
Process->Header.Type = ProcessObject; Process->Header.Type = ProcessObject;
@@ -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,15 +73,15 @@
*/ */
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,
IN PVOID StartContext, IN PVOID StartContext,
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,11 +246,11 @@ 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,
IN OUT PVOID *SystemArgument2) IN OUT PVOID *SystemArgument2)
{ {
/* No action here */ /* No action here */
} }
@@ -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,8 +72,8 @@ 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;
ULONG_PTR LongValue; ULONG_PTR LongValue;
@@ -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,8 +151,8 @@ 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,9 +30,9 @@
*/ */
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)
{ {
/* Initialize semaphore header and limit */ /* Initialize semaphore header and limit */
Semaphore->Header.Type = SemaphoreObject; Semaphore->Header.Type = SemaphoreObject;
@@ -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,11 +82,13 @@ 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)
{ {
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,9 +53,9 @@ 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)
{ {
PSYSTEM_RESOURCE_HEADER Resource; PSYSTEM_RESOURCE_HEADER Resource;
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
@@ -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,10 +180,10 @@ 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)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
@@ -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);