Migrate KE subsystem to C++
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/amd64/irqs.c
|
||||
* FILE: xtoskrnl/ke/amd64/irq.cc
|
||||
* DESCRIPTION: Kernel interrupts support for amd64 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Sets new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
@@ -24,8 +28,8 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
@@ -37,3 +41,16 @@ KeSetInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
KE::Irq::SetInterruptHandler(Vector, Handler);
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/amd64/krnlinit.c
|
||||
* FILE: xtoskrnl/ke/amd64/krnlinit.cc
|
||||
* DESCRIPTION: CPU architecture specific kernel initialization
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* This routine initializes XT kernel.
|
||||
*
|
||||
@@ -18,7 +22,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeKernel(VOID)
|
||||
KernelInit::InitializeKernel(VOID)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
|
||||
@@ -28,7 +32,7 @@ KepInitializeKernel(VOID)
|
||||
{
|
||||
/* Hardware layer initialization failed, kernel panic */
|
||||
DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
|
||||
KePanic(0);
|
||||
Crash::Panic(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +45,7 @@ KepInitializeKernel(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeMachine(VOID)
|
||||
KernelInit::InitializeMachine(VOID)
|
||||
{
|
||||
/* Re-enable IDE interrupts */
|
||||
HlIoPortOutByte(0x376, 0);
|
||||
@@ -66,7 +70,7 @@ KepInitializeMachine(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepStartKernel(VOID)
|
||||
KernelInit::StartKernel(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
ULONG_PTR PageDirectory[2];
|
||||
@@ -74,8 +78,8 @@ KepStartKernel(VOID)
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
/* Get processor control block and current thread */
|
||||
Prcb = KeGetCurrentProcessorControlBlock();
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
Prcb = Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = Processor::GetCurrentThread();
|
||||
|
||||
/* Get current process */
|
||||
CurrentProcess = CurrentThread->ApcState.Process;
|
||||
@@ -84,23 +88,22 @@ KepStartKernel(VOID)
|
||||
PoInitializeProcessorControlBlock(Prcb);
|
||||
|
||||
/* Save processor state */
|
||||
KepSaveProcessorState(&Prcb->ProcessorState);
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
KeLowerRunLevel(APC_LEVEL);
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize XTOS kernel */
|
||||
KepInitializeKernel();
|
||||
InitializeKernel();
|
||||
|
||||
/* Initialize Idle process */
|
||||
RtlInitializeListHead(&KepProcessListHead);
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE);
|
||||
KThread::InitializeThread(CurrentProcess, CurrentThread, nullptr, nullptr, nullptr, nullptr, nullptr, ArGetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
@@ -109,12 +112,12 @@ KepStartKernel(VOID)
|
||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n");
|
||||
for(;;);
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches execution to a new boot stack and transfers control to the KepStartKernel() routine.
|
||||
* Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -122,20 +125,28 @@ KepStartKernel(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepSwitchBootStack()
|
||||
KernelInit::SwitchBootStack(VOID)
|
||||
{
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
ULONG_PTR Stack;
|
||||
PVOID StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack and jump to KepStartKernel() */
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KernelInit::StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */
|
||||
__asm__ volatile("mov %0, %%rdx\n"
|
||||
"xor %%rbp, %%rbp\n"
|
||||
"mov %%rdx, %%rsp\n"
|
||||
"sub %1, %%rsp\n"
|
||||
"jmp KepStartKernel\n"
|
||||
"jmp *%2\n"
|
||||
:
|
||||
: "m" (Stack),
|
||||
"i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
|
||||
"p" (KepStartKernel)
|
||||
"r" (StartKernel)
|
||||
: "rdx", "rbp", "rsp", "memory");
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/amd64/kthread.c
|
||||
* FILE: xtoskrnl/ke/amd64/kthread.cc
|
||||
* DESCRIPTION: AMD64 thread manipulation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes CPU architecture dependent context of a thread.
|
||||
*
|
||||
@@ -33,7 +37,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeThreadContext(IN PKTHREAD Thread,
|
||||
KThread::InitializeThreadContext(IN PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
@@ -116,3 +120,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread,
|
||||
/* Set thread stack */
|
||||
Thread->KernelStack = &ThreadFrame->SwitchFrame;
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -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
162
xtoskrnl/ke/amd64/proc.cc
Normal 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);
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/apc.c
|
||||
* FILE: xtoskrnl/ke/apc.cc
|
||||
* DESCRIPTION: Kernel APC objects support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes an APC object.
|
||||
*
|
||||
@@ -42,14 +46,14 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeApc(IN PKAPC Apc,
|
||||
IN PKTHREAD Thread,
|
||||
IN KAPC_ENVIRONMENT Environment,
|
||||
IN PKKERNEL_ROUTINE KernelRoutine,
|
||||
IN PKRUNDOWN_ROUTINE RundownRoutine,
|
||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||
IN KPROCESSOR_MODE ApcMode,
|
||||
IN PVOID Context)
|
||||
Apc::InitializeApc(IN PKAPC Apc,
|
||||
IN PKTHREAD Thread,
|
||||
IN KAPC_ENVIRONMENT Environment,
|
||||
IN PKKERNEL_ROUTINE KernelRoutine,
|
||||
IN PKRUNDOWN_ROUTINE RundownRoutine,
|
||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||
IN KPROCESSOR_MODE ApcMode,
|
||||
IN PVOID Context)
|
||||
{
|
||||
/* Set APC type and thread */
|
||||
Apc->Type = ApcObject;
|
||||
@@ -89,3 +93,5 @@ KeInitializeApc(IN PKAPC Apc,
|
||||
/* Mark APC as not inserted yet */
|
||||
Apc->Inserted = FALSE;
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,25 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/info.c
|
||||
* DESCRIPTION: Generic kernel information support
|
||||
* FILE: xtoskrnl/ke/bootinfo.cc
|
||||
* DESCRIPTION: Bootloader-provided system information handling support
|
||||
* DEVELOPERS: Aiken Harris <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).
|
||||
*
|
||||
@@ -18,9 +29,9 @@
|
||||
*/
|
||||
XTAPI
|
||||
SYSTEM_FIRMWARE_TYPE
|
||||
KeGetFirmwareType(VOID)
|
||||
BootInformation::GetFirmwareType(VOID)
|
||||
{
|
||||
return KeInitializationBlock->FirmwareInformation.FirmwareType;
|
||||
return InitializationBlock->FirmwareInformation.FirmwareType;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,17 +49,14 @@ KeGetFirmwareType(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeGetKernelParameter(IN PCWSTR ParameterName,
|
||||
OUT PCWSTR *Parameter)
|
||||
BootInformation::GetKernelParameter(IN PCWSTR ParameterName,
|
||||
OUT PCWSTR *Parameter)
|
||||
{
|
||||
PCWSTR KernelParameters,Match, SearchStart;
|
||||
PCWSTR Match, SearchStart;
|
||||
SIZE_T ParameterNameLength;
|
||||
|
||||
/* Get the kernel parameters */
|
||||
KernelParameters = KeInitializationBlock->KernelParameters;
|
||||
|
||||
/* Validate input parameters */
|
||||
if(!KernelParameters || !ParameterName || !Parameter)
|
||||
if(!ParameterName || !Parameter)
|
||||
{
|
||||
/* Invalid input parameters, return error */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
@@ -63,16 +71,16 @@ KeGetKernelParameter(IN PCWSTR ParameterName,
|
||||
}
|
||||
|
||||
/* Assume the requested parameter is not present in the kernel parameters */
|
||||
*Parameter = NULL;
|
||||
*Parameter = nullptr;
|
||||
|
||||
/* Start searching from the beginning of the list */
|
||||
SearchStart = KernelParameters;
|
||||
SearchStart = InitializationBlock->KernelParameters;
|
||||
|
||||
/* Search for the parameter name */
|
||||
while((Match = RtlFindWideStringInsensitive(SearchStart, ParameterName)))
|
||||
{
|
||||
/* Check if the match is at the start of the string or preceded by a space */
|
||||
if(Match == KernelParameters || *(Match - 1) == L' ')
|
||||
if(Match == InitializationBlock->KernelParameters || *(Match - 1) == L' ')
|
||||
{
|
||||
/* Check the character after the match to avoid matching prefixes */
|
||||
if(Match[ParameterNameLength] == L'\0' ||
|
||||
@@ -92,3 +100,50 @@ KeGetKernelParameter(IN PCWSTR ParameterName,
|
||||
/* Parameter not found */
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
XTAPI
|
||||
PLIST_ENTRY
|
||||
BootInformation::GetSystemResources(VOID)
|
||||
{
|
||||
return &InitializationBlock->SystemResourcesListHead;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
BootInformation::SetInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block)
|
||||
{
|
||||
InitializationBlock = Block;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeGetKernelParameter(IN PCWSTR ParameterName,
|
||||
OUT PCWSTR *Parameter)
|
||||
{
|
||||
return KE::BootInformation::GetKernelParameter(ParameterName, Parameter);
|
||||
}
|
||||
|
||||
XTCLINK
|
||||
XTAPI
|
||||
PKERNEL_INITIALIZATION_BLOCK
|
||||
KeGetInitializationBlock(VOID)
|
||||
{
|
||||
return KE::BootInformation::GetInitializationBlock();
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/panic.c
|
||||
* FILE: xtoskrnl/ke/panic.cc
|
||||
* DESCRIPTION: System shutdown and kernel panic mechanism
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Halts the system.
|
||||
*
|
||||
@@ -18,14 +22,14 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeHaltSystem(VOID)
|
||||
Crash::HaltSystem(VOID)
|
||||
{
|
||||
/* Enter infinite loop */
|
||||
for(;;)
|
||||
{
|
||||
/* Halt system */
|
||||
ArClearInterruptFlag();
|
||||
ArHalt();
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunc::Halt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +45,9 @@ KeHaltSystem(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KePanic(IN ULONG Code)
|
||||
Crash::Panic(IN ULONG Code)
|
||||
{
|
||||
KePanicEx(Code, 0, 0, 0, 0);
|
||||
PanicEx(Code, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,12 +74,33 @@ KePanic(IN ULONG Code)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KePanicEx(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4)
|
||||
Crash::PanicEx(IN ULONG Code,
|
||||
IN ULONG_PTR Parameter1,
|
||||
IN ULONG_PTR Parameter2,
|
||||
IN ULONG_PTR Parameter3,
|
||||
IN ULONG_PTR Parameter4)
|
||||
{
|
||||
KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code);
|
||||
KeHaltSystem();
|
||||
HaltSystem();
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
KeHaltSystem(VOID)
|
||||
{
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
KePanic(ULONG Code)
|
||||
{
|
||||
KE::Crash::Panic(Code);
|
||||
}
|
34
xtoskrnl/ke/data.cc
Normal file
34
xtoskrnl/ke/data.cc
Normal 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 */
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/dpc.c
|
||||
* FILE: xtoskrnl/ke/dpc.cc
|
||||
* DESCRIPTION: Deferred Procedure Call (DPC) support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes Deferred Procedure Call (DPC) object.
|
||||
*
|
||||
@@ -27,9 +31,9 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeDpc(IN PKDPC Dpc,
|
||||
IN PKDEFERRED_ROUTINE DpcRoutine,
|
||||
IN PVOID DpcContext)
|
||||
Dpc::InitializeDpc(IN PKDPC Dpc,
|
||||
IN PKDEFERRED_ROUTINE DpcRoutine,
|
||||
IN PVOID DpcContext)
|
||||
{
|
||||
/* Initialize DPC */
|
||||
Dpc->Type = DpcObject;
|
||||
@@ -60,9 +64,9 @@ KeInitializeDpc(IN PKDPC Dpc,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeThreadedDpc(IN PKDPC Dpc,
|
||||
IN PKDEFERRED_ROUTINE DpcRoutine,
|
||||
IN PVOID DpcContext)
|
||||
Dpc::InitializeThreadedDpc(IN PKDPC Dpc,
|
||||
IN PKDEFERRED_ROUTINE DpcRoutine,
|
||||
IN PVOID DpcContext)
|
||||
{
|
||||
/* Initialize threaded DPC */
|
||||
Dpc->Type = ThreadedDpcObject;
|
||||
@@ -90,7 +94,7 @@ KeInitializeThreadedDpc(IN PKDPC Dpc,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetTargetProcessorDpc(IN PKDPC Dpc,
|
||||
Dpc::SetTargetProcessor(IN PKDPC Dpc,
|
||||
IN CCHAR Number)
|
||||
{
|
||||
Dpc->Number = MAXIMUM_PROCESSORS + Number;
|
||||
@@ -108,9 +112,9 @@ KeSetTargetProcessorDpc(IN PKDPC Dpc,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeSignalCallDpcDone(IN PVOID SystemArgument)
|
||||
Dpc::SignalCallDone(IN PVOID SystemArgument)
|
||||
{
|
||||
RtlAtomicDecrement32(SystemArgument);
|
||||
RtlAtomicDecrement32((PLONG)SystemArgument);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +129,7 @@ KeSignalCallDpcDone(IN PVOID SystemArgument)
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
KeSignalCallDpcSynchronize(IN PVOID SystemArgument)
|
||||
Dpc::SignalCallSynchronize(IN PVOID SystemArgument)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
@@ -145,7 +149,9 @@ KeSignalCallDpcSynchronize(IN PVOID SystemArgument)
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KepRetireDpcList(IN PKPROCESSOR_CONTROL_BLOCK Prcb)
|
||||
Dpc::RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/event.c
|
||||
* FILE: xtoskrnl/ke/event.cc
|
||||
* DESCRIPTION: Kernel events support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Clears the signal state of the event.
|
||||
*
|
||||
@@ -21,7 +25,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeClearEvent(IN PKEVENT Event)
|
||||
Event::ClearEvent(IN PKEVENT Event)
|
||||
{
|
||||
/* Clear event's signal state */
|
||||
Event->Header.SignalState = FALSE;
|
||||
@@ -45,9 +49,9 @@ KeClearEvent(IN PKEVENT Event)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeEvent(OUT PKEVENT Event,
|
||||
IN KEVENT_TYPE EventType,
|
||||
IN BOOLEAN InitialState)
|
||||
Event::InitializeEvent(OUT PKEVENT Event,
|
||||
IN KEVENT_TYPE EventType,
|
||||
IN BOOLEAN InitialState)
|
||||
{
|
||||
/* Initialize event dispatcher header */
|
||||
Event->Header.Type = EventType;
|
||||
@@ -75,11 +79,13 @@ KeInitializeEvent(OUT PKEVENT Event,
|
||||
*/
|
||||
XTAPI
|
||||
LONG
|
||||
KeSetEvent(IN PKEVENT Event,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Wait)
|
||||
Event::SetEvent(IN PKEVENT Event,
|
||||
IN KPRIORITY Increment,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace */
|
482
xtoskrnl/ke/exports.cc
Normal file
482
xtoskrnl/ke/exports.cc
Normal 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);
|
||||
}
|
@@ -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;
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/i686/irqs.c
|
||||
* FILE: xtoskrnl/ke/i686/irq.cc
|
||||
* DESCRIPTION: Kernel interrupts support for i686 architecture
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Sets new interrupt handler for the existing IDT entry.
|
||||
*
|
||||
@@ -24,7 +28,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetInterruptHandler(IN ULONG Vector,
|
||||
Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
@@ -36,3 +40,17 @@ KeSetInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
KE::Irq::SetInterruptHandler(Vector, Handler);
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/i686/krnlinit.c
|
||||
* FILE: xtoskrnl/ke/i686/krnlinit.cc
|
||||
* DESCRIPTION: CPU architecture specific kernel initialization
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* This routine initializes XT kernel.
|
||||
*
|
||||
@@ -18,7 +22,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeKernel(VOID)
|
||||
KernelInit::InitializeKernel(VOID)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
|
||||
@@ -28,7 +32,7 @@ KepInitializeKernel(VOID)
|
||||
{
|
||||
/* Hardware layer initialization failed, kernel panic */
|
||||
DebugPrint(L"Failed to initialize hardware layer subsystem!\n");
|
||||
KePanic(0);
|
||||
Crash::Panic(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +45,7 @@ KepInitializeKernel(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeMachine(VOID)
|
||||
KernelInit::InitializeMachine(VOID)
|
||||
{
|
||||
/* Re-enable IDE interrupts */
|
||||
HlIoPortOutByte(0x376, 0);
|
||||
@@ -66,7 +70,7 @@ KepInitializeMachine(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepStartKernel(VOID)
|
||||
KernelInit::StartKernel(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
ULONG_PTR PageDirectory[2];
|
||||
@@ -74,8 +78,8 @@ KepStartKernel(VOID)
|
||||
PKTHREAD CurrentThread;
|
||||
|
||||
/* Get processor control block and current thread */
|
||||
Prcb = KeGetCurrentProcessorControlBlock();
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
Prcb = Processor::GetCurrentProcessorControlBlock();
|
||||
CurrentThread = Processor::GetCurrentThread();
|
||||
|
||||
/* Get current process */
|
||||
CurrentProcess = CurrentThread->ApcState.Process;
|
||||
@@ -84,23 +88,22 @@ KepStartKernel(VOID)
|
||||
PoInitializeProcessorControlBlock(Prcb);
|
||||
|
||||
/* Save processor state */
|
||||
KepSaveProcessorState(&Prcb->ProcessorState);
|
||||
Processor::SaveProcessorState(&Prcb->ProcessorState);
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
KeLowerRunLevel(APC_LEVEL);
|
||||
RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize XTOS kernel */
|
||||
KepInitializeKernel();
|
||||
InitializeKernel();
|
||||
|
||||
/* Initialize Idle process */
|
||||
RtlInitializeListHead(&KepProcessListHead);
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KeInitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE);
|
||||
KThread::InitializeThread(CurrentProcess, CurrentThread, nullptr, nullptr, nullptr, nullptr, nullptr, ArGetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
@@ -109,12 +112,12 @@ KepStartKernel(VOID)
|
||||
CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KepStartKernel() finished. Entering infinite loop.\n");
|
||||
for(;;);
|
||||
DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n");
|
||||
Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches execution to a new boot stack and transfers control to the specified routine.
|
||||
* Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -122,22 +125,30 @@ KepStartKernel(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepSwitchBootStack()
|
||||
KernelInit::SwitchBootStack(VOID)
|
||||
{
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
ULONG_PTR Stack;
|
||||
PVOID StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1);
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KernelInit::StartKernel;
|
||||
|
||||
/* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */
|
||||
__asm__ volatile("mov %0, %%edx\n"
|
||||
"xor %%ebp, %%ebp\n"
|
||||
"mov %%edx, %%esp\n"
|
||||
"sub %1, %%esp\n"
|
||||
"push %2\n"
|
||||
"jmp _KepStartKernel@0\n"
|
||||
"jmp *%3\n"
|
||||
:
|
||||
: "m" (Stack),
|
||||
"i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
|
||||
"i" (CR0_EM | CR0_MP | CR0_TS),
|
||||
"p" (KepStartKernel)
|
||||
"r" (StartKernel)
|
||||
: "edx", "ebp", "esp", "memory");
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/i686/kthread.c
|
||||
* FILE: xtoskrnl/ke/i686/kthread.cc
|
||||
* DESCRIPTION: I686 thread manipulation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Initializes CPU architecture dependent context of a thread.
|
||||
*
|
||||
@@ -33,17 +37,17 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeThreadContext(IN PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
IN PCONTEXT ContextRecord)
|
||||
KThread::InitializeThreadContext(IN PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
IN PCONTEXT ContextRecord)
|
||||
{
|
||||
PKTHREAD_INIT_FRAME ThreadFrame;
|
||||
PFX_SAVE_FORMAT FxSaveFormat;
|
||||
|
||||
/* Set initial thread frame */
|
||||
ThreadFrame = (PKTHREAD_INIT_FRAME)(Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME));
|
||||
ThreadFrame = (PKTHREAD_INIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME));
|
||||
|
||||
/* Fill floating point save area with zeroes */
|
||||
RtlZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA));
|
||||
@@ -114,3 +118,5 @@ KepInitializeThreadContext(IN PKTHREAD Thread,
|
||||
/* Set thread stack */
|
||||
Thread->KernelStack = &ThreadFrame->SwitchFrame;
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -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
150
xtoskrnl/ke/i686/proc.cc
Normal 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);
|
||||
}
|
@@ -1,14 +1,25 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/kprocess.c
|
||||
* FILE: xtoskrnl/ke/kprocess.cc
|
||||
* DESCRIPTION: XT kernel process manipulation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
XTAPI
|
||||
PEPROCESS
|
||||
KProcess::GetInitialProcess(VOID)
|
||||
{
|
||||
return &InitialProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the process.
|
||||
*
|
||||
@@ -33,11 +44,11 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeProcess(IN OUT PKPROCESS Process,
|
||||
IN KPRIORITY Priority,
|
||||
IN KAFFINITY Affinity,
|
||||
IN PULONG_PTR DirectoryTable,
|
||||
IN BOOLEAN Alignment)
|
||||
KProcess::InitializeProcess(IN OUT PKPROCESS Process,
|
||||
IN KPRIORITY Priority,
|
||||
IN KAFFINITY Affinity,
|
||||
IN PULONG_PTR DirectoryTable,
|
||||
IN BOOLEAN Alignment)
|
||||
{
|
||||
/* Initialize process dispatcher header */
|
||||
Process->Header.Type = ProcessObject;
|
||||
@@ -67,3 +78,19 @@ KeInitializeProcess(IN OUT PKPROCESS Process,
|
||||
/* Set initial process state */
|
||||
Process->State = ProcessInMemory;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeProcess(IN OUT PKPROCESS Process,
|
||||
IN KPRIORITY Priority,
|
||||
IN KAFFINITY Affinity,
|
||||
IN PULONG_PTR DirectoryTable,
|
||||
IN BOOLEAN Alignment)
|
||||
{
|
||||
KE::KProcess::InitializeProcess(Process, Priority, Affinity, DirectoryTable, Alignment);
|
||||
}
|
@@ -1,14 +1,17 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/krnlinit.c
|
||||
* FILE: xtoskrnl/ke/krnlinit.cc
|
||||
* DESCRIPTION: XT kernel initialization
|
||||
* DEVELOPERS: Rafal Kupiec <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.
|
||||
*
|
||||
@@ -23,31 +26,31 @@ XTAPI
|
||||
VOID
|
||||
KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
||||
{
|
||||
/* Save the kernel initialization block */
|
||||
KeInitializationBlock = Parameters;
|
||||
|
||||
/* Verify kernel and boot loader compatibility */
|
||||
if(KeInitializationBlock->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) ||
|
||||
KeInitializationBlock->BlockVersion != INITIALIZATION_BLOCK_VERSION ||
|
||||
KeInitializationBlock->ProtocolVersion != BOOT_PROTOCOL_VERSION)
|
||||
if(Parameters->BlockSize != sizeof(KERNEL_INITIALIZATION_BLOCK) ||
|
||||
Parameters->BlockVersion != INITIALIZATION_BLOCK_VERSION ||
|
||||
Parameters->ProtocolVersion != BOOT_PROTOCOL_VERSION)
|
||||
{
|
||||
/* Kernel and boot loader version mismatch */
|
||||
KeHaltSystem();
|
||||
Crash::HaltSystem();
|
||||
}
|
||||
|
||||
/* Save the kernel initialization block */
|
||||
BootInformation::SetInitializationBlock(Parameters);
|
||||
|
||||
/* Check if debugging enabled and if boot loader provided routine for debug printing */
|
||||
if(DEBUG && KeInitializationBlock->LoaderInformation.DbgPrint)
|
||||
if(DEBUG && BootInformation::GetDebugPrint())
|
||||
{
|
||||
/* Use loader's provided DbgPrint() routine for early printing to serial console */
|
||||
KdSetPrintRoutine(KeInitializationBlock->LoaderInformation.DbgPrint);
|
||||
KdSetPrintRoutine(BootInformation::GetDebugPrint());
|
||||
DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME);
|
||||
}
|
||||
|
||||
/* Initialize boot CPU */
|
||||
ArInitializeProcessor(NULL);
|
||||
AR::ProcSup::InitializeProcessor(NULL);
|
||||
|
||||
/* Initialize system resources */
|
||||
KepInitializeSystemResources();
|
||||
SystemResources::InitializeResources();
|
||||
|
||||
/* Check if debugging enabled */
|
||||
if(DEBUG)
|
||||
@@ -63,11 +66,11 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
||||
XTOS_COMPILER_NAME, XTOS_COMPILER_VERSION);
|
||||
|
||||
/* Architecture specific kernel initialization */
|
||||
KepInitializeMachine();
|
||||
KernelInit::InitializeMachine();
|
||||
|
||||
/* Raise to HIGH runlevel */
|
||||
KeRaiseRunLevel(HIGH_LEVEL);
|
||||
RunLevel::RaiseRunLevel(HIGH_LEVEL);
|
||||
|
||||
/* Switch the boot stack and transfer control to the KepStartKernel() routine */
|
||||
KepSwitchBootStack();
|
||||
KernelInit::SwitchBootStack();
|
||||
}
|
@@ -1,14 +1,45 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/kthread.c
|
||||
* FILE: xtoskrnl/ke/kthread.cc
|
||||
* DESCRIPTION: XT kernel thread manipulation support
|
||||
* DEVELOPERS: Rafal Kupiec <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.
|
||||
*
|
||||
@@ -42,15 +73,15 @@
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeInitializeThread(IN PKPROCESS Process,
|
||||
IN OUT PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
IN PCONTEXT Context,
|
||||
IN PVOID EnvironmentBlock,
|
||||
IN PVOID Stack,
|
||||
IN BOOLEAN StartThread)
|
||||
KThread::InitializeThread(IN PKPROCESS Process,
|
||||
IN OUT PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
IN PCONTEXT Context,
|
||||
IN PVOID EnvironmentBlock,
|
||||
IN PVOID Stack,
|
||||
IN BOOLEAN RunThread)
|
||||
{
|
||||
PKWAIT_BLOCK TimerWaitBlock;
|
||||
BOOLEAN Allocation;
|
||||
@@ -86,10 +117,7 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
Thread->AdjustReason = AdjustNone;
|
||||
|
||||
/* Initialize thread lock */
|
||||
KeInitializeSpinLock(&Thread->ThreadLock);
|
||||
|
||||
/* Set thread service table */
|
||||
Thread->ServiceTable = KeServiceDescriptorTable;
|
||||
SpinLock::InitializeSpinLock(&Thread->ThreadLock);
|
||||
|
||||
/* Initialize thread APC */
|
||||
Thread->ApcStatePointer[0] = &Thread->ApcState;
|
||||
@@ -103,17 +131,17 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
RtlInitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
|
||||
|
||||
/* Initialize APC queue lock */
|
||||
KeInitializeSpinLock(&Thread->ApcQueueLock);
|
||||
SpinLock::InitializeSpinLock(&Thread->ApcQueueLock);
|
||||
|
||||
/* Initialize kernel-mode suspend APC */
|
||||
KeInitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, KepSuspendNop,
|
||||
KepSuspendRundown, KepSuspendThread, KernelMode, NULL);
|
||||
Apc::InitializeApc(&Thread->SuspendApc, Thread, OriginalApcEnvironment, SuspendNop,
|
||||
SuspendRundown, SuspendThread, KernelMode, NULL);
|
||||
|
||||
/* Initialize suspend semaphore */
|
||||
KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
|
||||
Semaphore::InitializeSemaphore(&Thread->SuspendSemaphore, 0, 2);
|
||||
|
||||
/* Initialize the builtin timer */
|
||||
KeInitializeTimer(&Thread->Timer, NotificationTimer);
|
||||
Timer::InitializeTimer(&Thread->Timer, NotificationTimer);
|
||||
TimerWaitBlock = &Thread->WaitBlock[KTIMER_WAIT_BLOCK];
|
||||
TimerWaitBlock->Object = &Thread->Timer;
|
||||
TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
|
||||
@@ -122,7 +150,7 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
TimerWaitBlock->WaitListEntry.Blink = &(&Thread->Timer)->Header.WaitListHead;
|
||||
|
||||
/* Initialize Thread Environment Block*/
|
||||
Thread->EnvironmentBlock = EnvironmentBlock;
|
||||
Thread->EnvironmentBlock = (PTHREAD_ENVIRONMENT_BLOCK)EnvironmentBlock;
|
||||
|
||||
/* Make sure there is a valid stack available */
|
||||
if(!Stack)
|
||||
@@ -141,12 +169,12 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
|
||||
Thread->InitialStack = Stack;
|
||||
Thread->StackBase = Stack;
|
||||
Thread->StackLimit = Stack - KERNEL_STACK_SIZE;
|
||||
Thread->StackLimit = (PVOID)((ULONG_PTR)Stack - KERNEL_STACK_SIZE);
|
||||
|
||||
__try
|
||||
{
|
||||
/* Initialize thread context */
|
||||
KepInitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context);
|
||||
InitializeThreadContext(Thread, SystemRoutine, StartRoutine, StartContext, Context);
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
@@ -167,10 +195,10 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
Thread->State = Initialized;
|
||||
|
||||
/* Check if thread should be started */
|
||||
if(StartThread)
|
||||
if(RunThread)
|
||||
{
|
||||
/* Start thread */
|
||||
KeStartThread(Thread);
|
||||
StartThread(Thread);
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
@@ -189,31 +217,11 @@ KeInitializeThread(IN PKPROCESS Process,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeStartThread(IN PKTHREAD Thread)
|
||||
KThread::StartThread(IN PKTHREAD Thread)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the dispatcher, switches context to a new thread and lowers runlevel to its original state.
|
||||
*
|
||||
* @param OldRunLevel
|
||||
* Supplies the original runlevel state.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KepExitDispatcher(IN KRUNLEVEL OldRunLevel)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Lower runlevel */
|
||||
KeLowerRunLevel(OldRunLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspend APC-built thread NOP routine. It takes no actions.
|
||||
*
|
||||
@@ -238,11 +246,11 @@ KepExitDispatcher(IN KRUNLEVEL OldRunLevel)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepSuspendNop(IN PKAPC Apc,
|
||||
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
|
||||
IN OUT PVOID *NormalContext,
|
||||
IN OUT PVOID *SystemArgument1,
|
||||
IN OUT PVOID *SystemArgument2)
|
||||
KThread::SuspendNop(IN PKAPC Apc,
|
||||
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
|
||||
IN OUT PVOID *NormalContext,
|
||||
IN OUT PVOID *SystemArgument1,
|
||||
IN OUT PVOID *SystemArgument2)
|
||||
{
|
||||
/* No action here */
|
||||
}
|
||||
@@ -259,7 +267,7 @@ KepSuspendNop(IN PKAPC Apc,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepSuspendRundown(IN PKAPC Apc)
|
||||
KThread::SuspendRundown(IN PKAPC Apc)
|
||||
{
|
||||
/* No action here */
|
||||
}
|
||||
@@ -282,9 +290,30 @@ KepSuspendRundown(IN PKAPC Apc)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepSuspendThread(IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
KThread::SuspendThread(IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeInitializeThread(IN PKPROCESS Process,
|
||||
IN OUT PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
IN PKSTART_ROUTINE StartRoutine,
|
||||
IN PVOID StartContext,
|
||||
IN PCONTEXT Context,
|
||||
IN PVOID EnvironmentBlock,
|
||||
IN PVOID Stack,
|
||||
IN BOOLEAN RunThread)
|
||||
{
|
||||
return KE::KThread::InitializeThread(Process, Thread, SystemRoutine, StartRoutine, StartContext, Context, EnvironmentBlock, Stack, RunThread);
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/kubsan.c
|
||||
* FILE: xtoskrnl/ke/kubsan.cc
|
||||
* DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Checks whether handled UBSAN error should be reported.
|
||||
*
|
||||
@@ -21,10 +25,10 @@
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location)
|
||||
KUbsan::CheckReport(PKUBSAN_SOURCE_LOCATION Location)
|
||||
{
|
||||
/* Make sure, this error should be reported */
|
||||
return !KepUbsanActiveFrame;
|
||||
return (BOOLEAN)!ActiveFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,11 +46,11 @@ KepCheckUbsanReport(PKUBSAN_SOURCE_LOCATION Location)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location,
|
||||
PCCHAR Reason)
|
||||
KUbsan::EnterFrame(PKUBSAN_SOURCE_LOCATION Location,
|
||||
PCCHAR Reason)
|
||||
{
|
||||
/* Enter UBSAN frame */
|
||||
KepUbsanActiveFrame = TRUE;
|
||||
ActiveFrame = TRUE;
|
||||
|
||||
/* Print generic error message to debug console */
|
||||
DebugPrint(L"UBSAN: Undefined behavior (%s) in %s:%d:%d\n",
|
||||
@@ -68,8 +72,8 @@ KepEnterUbsanFrame(PKUBSAN_SOURCE_LOCATION Location,
|
||||
*/
|
||||
XTCDECL
|
||||
LONGLONG
|
||||
KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
PVOID Value)
|
||||
KUbsan::GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
PVOID Value)
|
||||
{
|
||||
ULONG BitWidth, ExtraBits;
|
||||
ULONG_PTR LongValue;
|
||||
@@ -102,7 +106,7 @@ KepGetSignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
*/
|
||||
XTCDECL
|
||||
PCCHAR
|
||||
KepGetUbsanTypeKind(UCHAR TypeCheckKind)
|
||||
KUbsan::GetTypeKind(UCHAR TypeCheckKind)
|
||||
{
|
||||
/* Get type kind name */
|
||||
switch(TypeCheckKind)
|
||||
@@ -147,8 +151,8 @@ KepGetUbsanTypeKind(UCHAR TypeCheckKind)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
PVOID Value)
|
||||
KUbsan::GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
PVOID Value)
|
||||
{
|
||||
ULONG BitWidth;
|
||||
|
||||
@@ -184,22 +188,22 @@ KepGetUnsignedUbsanValue(PKUBSAN_TYPE_DESCRIPTOR Type,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
PVOID Lhs,
|
||||
PVOID Rhs)
|
||||
KUbsan::HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
PVOID Lhs,
|
||||
PVOID Rhs)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Division-Overflow");
|
||||
EnterFrame(&Data->Location, "Division-Overflow");
|
||||
|
||||
/* Check if signed type, which value is -1 */
|
||||
if((Data->Type->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->Type, Rhs) == -1))
|
||||
if((Data->Type->TypeInfo & 1) && (GetSignedValue(Data->Type, Rhs) == -1))
|
||||
{
|
||||
/* Division by -1, print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Division by -1 cannot be represented in type %s\n", Data->Type->TypeName);
|
||||
@@ -211,7 +215,7 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
}
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,25 +236,25 @@ KepHandleUbsanDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
KUbsan::HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow");
|
||||
EnterFrame(&Data->Location, "Float-Cast-Overflow");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"Value of type %s is outside the range of type %s\n", Data->LhsType->TypeName, Data->RhsType->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,25 +272,25 @@ KepHandleUbsanFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
KUbsan::HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Float-Cast-Overflow");
|
||||
EnterFrame(&Data->Location, "Float-Cast-Overflow");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Indirect function call through %P address of a wrong type %s\n",
|
||||
(PVOID)Pointer, Data->Type->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,25 +311,25 @@ KepHandleUbsanFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
KUbsan::HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Integer-Overflow");
|
||||
EnterFrame(&Data->Location, "Integer-Overflow");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: The result of an arithmetic operation cannot be represented in type %s\n", Data->Type->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,17 +344,17 @@ KepHandleUbsanIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
|
||||
KUbsan::HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Invalid-Builtin");
|
||||
EnterFrame(&Data->Location, "Invalid-Builtin");
|
||||
|
||||
/* Check kind of UBSAN error */
|
||||
if(Data->Kind == 0 || Data->Kind == 1)
|
||||
@@ -365,7 +369,7 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
|
||||
}
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,25 +387,25 @@ KepHandleUbsanInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
KUbsan::HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Misaligned-Access");
|
||||
EnterFrame(&Data->Location, "Misaligned-Access");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: %s misaligned address %p for type %s which requires %ld byte alignment\n",
|
||||
KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment);
|
||||
GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName, Data->Alignment);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,24 +423,24 @@ KepHandleUbsanMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR OldValue)
|
||||
KUbsan::HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR OldValue)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Negate-Overflow");
|
||||
EnterFrame(&Data->Location, "Negate-Overflow");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Negation of %lu cannot be represented in type %s\n", OldValue, Data->Type->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
|
||||
@@ -455,23 +459,23 @@ KepHandleUbsanNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)
|
||||
KUbsan::HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "NULL-Pointer-Dereference");
|
||||
EnterFrame(&Data->Location, "NULL-Pointer-Dereference");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", KepGetUbsanTypeKind(Data->TypeCheckKind), Data->Type->TypeName);
|
||||
DebugPrint(L"UBSAN: %s NULL pointer of type %s\n", GetTypeKind(Data->TypeCheckKind), Data->Type->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,25 +493,25 @@ KepHandleUbsanNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
KUbsan::HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Object-Size-Mismatch");
|
||||
EnterFrame(&Data->Location, "Object-Size-Mismatch");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: %s address %p with insufficient space for an object of type %s\n",
|
||||
KepGetUbsanTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName);
|
||||
GetTypeKind(Data->TypeCheckKind), (PVOID)Pointer, Data->Type->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,24 +529,24 @@ KepHandleUbsanObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
|
||||
ULONG_PTR Index)
|
||||
KUbsan::HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
|
||||
ULONG_PTR Index)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Array-Index-Out-Of-Bounds");
|
||||
EnterFrame(&Data->Location, "Array-Index-Out-Of-Bounds");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: index is out of range for type %s", Data->ArrayType->TypeName);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,26 +567,26 @@ KepHandleUbsanOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
KUbsan::HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
{
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Pointer-Overflow");
|
||||
EnterFrame(&Data->Location, "Pointer-Overflow");
|
||||
|
||||
/* Print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Pointer operation %s %p to %p\n",
|
||||
Lhs > Rhs ? "overflowed" : "underflowed", (PVOID)Lhs, (PVOID)Rhs);
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
|
||||
@@ -604,52 +608,52 @@ KepHandleUbsanPointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
KUbsan::HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
|
||||
ULONG_PTR Lhs,
|
||||
ULONG_PTR Rhs)
|
||||
{
|
||||
ULONG LhsBitWidth;
|
||||
|
||||
/* Check if this error was already reported */
|
||||
if(!KepCheckUbsanReport(&Data->Location))
|
||||
if(!CheckReport(&Data->Location))
|
||||
{
|
||||
/* Don't report twice */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enter UBSAN frame */
|
||||
KepEnterUbsanFrame(&Data->Location, "Shift-Out-Of-Bounds");
|
||||
EnterFrame(&Data->Location, "Shift-Out-Of-Bounds");
|
||||
|
||||
/* Calculate Lhs bit width */
|
||||
LhsBitWidth = 1 << (Data->LhsType->TypeInfo >> 1);
|
||||
|
||||
/* Check a type of out of bounds error */
|
||||
if((Data->RhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs) < 0))
|
||||
if((Data->RhsType->TypeInfo & 1) && (GetSignedValue(Data->RhsType, (PVOID)Rhs) < 0))
|
||||
{
|
||||
/* Negative shift exponent, print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs));
|
||||
DebugPrint(L"UBSAN: Shift exponent %lld is negative\n", GetSignedValue(Data->RhsType, (PVOID)Rhs));
|
||||
}
|
||||
else if((Data->LhsType->TypeInfo & 1) && (KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs) < 0))
|
||||
else if((Data->LhsType->TypeInfo & 1) && (GetSignedValue(Data->LhsType, (PVOID)Lhs) < 0))
|
||||
{
|
||||
/* Negative left shift value, print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Left shift of negative value %lld\n", KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs));
|
||||
DebugPrint(L"UBSAN: Left shift of negative value %lld\n", GetSignedValue(Data->LhsType, (PVOID)Lhs));
|
||||
}
|
||||
else if(KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth)
|
||||
else if(GetUnsignedValue(Data->RhsType, (PVOID)Rhs) >= LhsBitWidth)
|
||||
{
|
||||
/* Shift exponent too large, print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Shift exponent %lld is too large for %u-bit type %s\n",
|
||||
KepGetUnsignedUbsanValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName);
|
||||
GetUnsignedValue(Data->RhsType, (PVOID)Rhs), LhsBitWidth, Data->LhsType->TypeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Left shift too large, print error message to debug console */
|
||||
DebugPrint(L"UBSAN: Left shift of %lld by %lld places cannot be represented in type %s\n",
|
||||
KepGetSignedUbsanValue(Data->LhsType, (PVOID)Lhs), KepGetSignedUbsanValue(Data->RhsType, (PVOID)Rhs),
|
||||
GetSignedValue(Data->LhsType, (PVOID)Lhs), GetSignedValue(Data->RhsType, (PVOID)Rhs),
|
||||
Data->LhsType->TypeName);
|
||||
}
|
||||
|
||||
/* Leave UBSAN frame */
|
||||
KepLeaveUbsanFrame();
|
||||
LeaveFrame();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -667,24 +671,24 @@ KepHandleUbsanShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
KUbsan::HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
ULONG_PTR Pointer)
|
||||
{
|
||||
/* Check the type of mismatch */
|
||||
if(!Pointer)
|
||||
{
|
||||
/* Handle NULL pointer dereference */
|
||||
KepHandleUbsanNullPointerDereference(Data);
|
||||
HandleNullPointerDereference(Data);
|
||||
}
|
||||
else if(Data->Alignment && (((Pointer) & ((typeof(Pointer))(Data->Alignment) - 1)) != 0))
|
||||
else if(Data->Alignment && (((Pointer) & ((decltype(Pointer))(Data->Alignment) - 1)) != 0))
|
||||
{
|
||||
/* Handle misaligned access */
|
||||
KepHandleUbsanMisalignedAccess(Data, Pointer);
|
||||
HandleMisalignedAccess(Data, Pointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle object size mismatch */
|
||||
KepHandleUbsanObjectSizeMismatch(Data, Pointer);
|
||||
HandleObjectSizeMismatch(Data, Pointer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,12 +701,17 @@ KepHandleUbsanTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
KepLeaveUbsanFrame()
|
||||
KUbsan::LeaveFrame()
|
||||
{
|
||||
/* Leave UBSAN frame */
|
||||
KepUbsanActiveFrame = FALSE;
|
||||
ActiveFrame = FALSE;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handles the addition overflow error. This is internal routine implementing ABI defined by CLANG UBSAN.
|
||||
*
|
||||
@@ -721,6 +730,7 @@ KepLeaveUbsanFrame()
|
||||
*
|
||||
* @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
__ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
@@ -728,7 +738,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN arithmetic overflow handler */
|
||||
KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -749,6 +759,7 @@ __ubsan_handle_add_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
*
|
||||
* @see https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/CodeGen/CodeGenFunction.h#L113
|
||||
*/
|
||||
XTCLINK
|
||||
XTCDECL
|
||||
VOID
|
||||
__ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
@@ -756,7 +767,7 @@ __ubsan_handle_divrem_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN PVOID Rhs)
|
||||
{
|
||||
/* Call UBSAN division overflow handler */
|
||||
KepHandleUbsanDivisionOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleDivisionOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -784,7 +795,7 @@ __ubsan_handle_float_cast_overflow(IN PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN float cast overflow handler */
|
||||
KepHandleUbsanFloatCastOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleFloatCastOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,7 +819,7 @@ __ubsan_handle_function_type_mismatch(IN PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Dat
|
||||
IN ULONG_PTR Pointer)
|
||||
{
|
||||
/* Call UBSAN function type mismatch handler */
|
||||
KepHandleUbsanFunctionTypeMismatch(Data, Pointer);
|
||||
KE::KUbsan::HandleFunctionTypeMismatch(Data, Pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -828,7 +839,7 @@ VOID
|
||||
__ubsan_handle_invalid_builtin(IN PKUBSAN_INVALID_BUILTIN_DATA Data)
|
||||
{
|
||||
/* Call UBSAN invalid builtin handler */
|
||||
KepHandleUbsanInvalidBuiltin(Data);
|
||||
KE::KUbsan::HandleInvalidBuiltin(Data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -856,7 +867,7 @@ __ubsan_handle_mul_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN arithmetic overflow handler */
|
||||
KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -880,7 +891,7 @@ __ubsan_handle_negate_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR OldValue)
|
||||
{
|
||||
/* Call UBSAN negate overflow handler */
|
||||
KepHandleUbsanNegateOverflow(Data, OldValue);
|
||||
KE::KUbsan::HandleNegateOverflow(Data, OldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -904,7 +915,7 @@ __ubsan_handle_out_of_bounds(IN PKUBSAN_OUT_OF_BOUNDS_DATA Data,
|
||||
IN ULONG_PTR Index)
|
||||
{
|
||||
/* Call UBSAN out of bounds handler */
|
||||
KepHandleUbsanOutOfBounds(Data, Index);
|
||||
KE::KUbsan::HandleOutOfBounds(Data, Index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -932,7 +943,7 @@ __ubsan_handle_pointer_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN pointer overflow handler */
|
||||
KepHandleUbsanPointerOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandlePointerOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -960,7 +971,7 @@ __ubsan_handle_shift_out_of_bounds(IN PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN out of bounds handler */
|
||||
KepHandleUbsanShiftOutOfBounds(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleShiftOutOfBounds(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -988,7 +999,7 @@ __ubsan_handle_sub_overflow(IN PKUBSAN_OVERFLOW_DATA Data,
|
||||
IN ULONG_PTR Rhs)
|
||||
{
|
||||
/* Call UBSAN arithmetic overflow handler */
|
||||
KepHandleUbsanIntegerOverflow(Data, Lhs, Rhs);
|
||||
KE::KUbsan::HandleIntegerOverflow(Data, Lhs, Rhs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1012,7 +1023,7 @@ __ubsan_handle_type_mismatch(IN PKUBSAN_TYPE_MISMATCH_DATA Data,
|
||||
IN ULONG_PTR Pointer)
|
||||
{
|
||||
/* Call UBSAN type mismatch handler */
|
||||
KepHandleUbsanTypeMismatch(Data, Pointer);
|
||||
KE::KUbsan::HandleTypeMismatch(Data, Pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1044,5 +1055,5 @@ __ubsan_handle_type_mismatch_v1(IN PKUBSAN_TYPE_MISMATCH_DATA_V1 Data,
|
||||
MismatchData.TypeCheckKind = Data->TypeCheckKind;
|
||||
|
||||
/* Call UBSAN type mismatch handler */
|
||||
KepHandleUbsanTypeMismatch(&MismatchData, Pointer);
|
||||
KE::KUbsan::HandleTypeMismatch(&MismatchData, Pointer);
|
||||
}
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/runlevel.c
|
||||
* FILE: xtoskrnl/ke/runlevel.cc
|
||||
* DESCRIPTION: Running Level management support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the current running level of the current processor.
|
||||
*
|
||||
@@ -18,7 +22,7 @@
|
||||
*/
|
||||
XTFASTCALL
|
||||
KRUNLEVEL
|
||||
KeGetCurrentRunLevel(VOID)
|
||||
RunLevel::GetCurrentRunLevel(VOID)
|
||||
{
|
||||
return HlGetRunLevel();
|
||||
}
|
||||
@@ -35,7 +39,7 @@ KeGetCurrentRunLevel(VOID)
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeLowerRunLevel(IN KRUNLEVEL RunLevel)
|
||||
RunLevel::LowerRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
KRUNLEVEL OldRunLevel;
|
||||
|
||||
@@ -62,7 +66,7 @@ KeLowerRunLevel(IN KRUNLEVEL RunLevel)
|
||||
*/
|
||||
XTFASTCALL
|
||||
KRUNLEVEL
|
||||
KeRaiseRunLevel(IN KRUNLEVEL RunLevel)
|
||||
RunLevel::RaiseRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
KRUNLEVEL OldRunLevel;
|
||||
|
||||
@@ -79,3 +83,33 @@ KeRaiseRunLevel(IN KRUNLEVEL RunLevel)
|
||||
/* Return old run level */
|
||||
return OldRunLevel;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
KRUNLEVEL
|
||||
KeGetCurrentRunLevel(VOID)
|
||||
{
|
||||
return KE::RunLevel::GetCurrentRunLevel();
|
||||
}
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeLowerRunLevel(KRUNLEVEL RunLevel)
|
||||
{
|
||||
KE::RunLevel::LowerRunLevel(RunLevel);
|
||||
}
|
||||
|
||||
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
|
||||
XTCLINK
|
||||
XTFASTCALL
|
||||
KRUNLEVEL
|
||||
KeRaiseRunLevel(KRUNLEVEL RunLevel)
|
||||
{
|
||||
return KE::RunLevel::RaiseRunLevel(RunLevel);
|
||||
}
|
@@ -1,16 +1,19 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/semphore.c
|
||||
* FILE: xtoskrnl/ke/semphore.cc
|
||||
* DESCRIPTION: Semaphores support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* initializes a kernel semaphore object.
|
||||
* Initializes a kernel semaphore object.
|
||||
*
|
||||
* @param Semaphore
|
||||
* Supplies a pointer to a semaphore object.
|
||||
@@ -27,9 +30,9 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
|
||||
IN LONG Count,
|
||||
IN LONG Limit)
|
||||
Semaphore::InitializeSemaphore(IN PKSEMAPHORE Semaphore,
|
||||
IN LONG Count,
|
||||
IN LONG Limit)
|
||||
{
|
||||
/* Initialize semaphore header and limit */
|
||||
Semaphore->Header.Type = SemaphoreObject;
|
||||
@@ -52,7 +55,7 @@ KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
|
||||
*/
|
||||
XTAPI
|
||||
LONG
|
||||
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore)
|
||||
Semaphore::ReadState(IN PKSEMAPHORE Semaphore)
|
||||
{
|
||||
/* Return semaphore's signal state */
|
||||
return Semaphore->Header.SignalState;
|
||||
@@ -79,11 +82,13 @@ KeReadSemaphoreState(IN PKSEMAPHORE Semaphore)
|
||||
*/
|
||||
XTAPI
|
||||
LONG
|
||||
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
|
||||
IN KPRIORITY Increment,
|
||||
IN LONG Adjustment,
|
||||
IN BOOLEAN Wait)
|
||||
Semaphore::ReleaseSemaphore(IN PKSEMAPHORE Semaphore,
|
||||
IN KPRIORITY Increment,
|
||||
IN LONG Adjustment,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/spinlock.c
|
||||
* FILE: xtoskrnl/ke/spinlock.cc
|
||||
* DESCRIPTION: Spinlocks support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Kernel Library */
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Acquires a specified queued spinlock.
|
||||
*
|
||||
@@ -21,10 +25,10 @@
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
SpinLock::AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
{
|
||||
/* Acquire the queued spinlock */
|
||||
KeAcquireSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);
|
||||
AcquireSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +43,7 @@ KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
/* Try to acquire the lock */
|
||||
while(RtlAtomicBitTestAndSet((PLONG)SpinLock, 0))
|
||||
@@ -68,7 +72,7 @@ KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||
SpinLock::InitializeSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
/* Zero initialize spinlock */
|
||||
*SpinLock = 0;
|
||||
@@ -86,10 +90,10 @@ KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
SpinLock::ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
{
|
||||
/* Clear the lock */
|
||||
KeReleaseSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);
|
||||
ReleaseSpinLock(KeGetCurrentProcessorControlBlock()->LockQueue[LockLevel].Lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +108,7 @@ KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
{
|
||||
/* Clear the lock */
|
||||
RtlAtomicAnd32((PLONG)SpinLock, 0);
|
||||
@@ -112,3 +116,5 @@ KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
/* Add an explicit memory barrier */
|
||||
ArReadWriteBarrier();
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,15 +1,18 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/sysres.c
|
||||
* FILE: xtoskrnl/ke/sysres.cc
|
||||
* DESCRIPTION: System resources management; This code is based on the MinocaOS implementation
|
||||
* Copyright(C) 2012 Minoca Corp. (https://github.com/minoca/os/blob/master/kernel/ke/sysres.c)
|
||||
* DEVELOPERS: Rafal Kupiec <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.
|
||||
*
|
||||
@@ -25,59 +28,11 @@
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
{
|
||||
/* Get system resource and acquire an ownership */
|
||||
return KepGetSystemResource(ResourceType, TRUE, ResourceHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.
|
||||
*
|
||||
* @param ResourceType
|
||||
* Supplies system resource type.
|
||||
*
|
||||
* @param ResourceHeader
|
||||
* Specifies a memory area where a pointer to the system resource header will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
{
|
||||
/* Get system resource without acquiring an ownership */
|
||||
return KepGetSystemResource(ResourceType, FALSE, ResourceHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases system resource.
|
||||
*
|
||||
* @param ResourceHeader
|
||||
* Specifies a pointer to the system resource header.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
{
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
ArClearInterruptFlag();
|
||||
KeAcquireSpinLock(&KepSystemResourcesLock);
|
||||
|
||||
/* Release resource lock */
|
||||
ResourceHeader->ResourceLocked = FALSE;
|
||||
|
||||
/* Release spinlock and enable interrupts */
|
||||
KeReleaseSpinLock(&KepSystemResourcesLock);
|
||||
ArSetInterruptFlag();
|
||||
return GetSystemResource(ResourceType, TRUE, ResourceHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,9 +53,9 @@ KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
IN BOOLEAN ResourceLock,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
IN BOOLEAN ResourceLock,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
{
|
||||
PSYSTEM_RESOURCE_HEADER Resource;
|
||||
PLIST_ENTRY ListEntry;
|
||||
@@ -111,15 +66,15 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Check if interrupts are enabled */
|
||||
Interrupts = ArInterruptsEnabled();
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
ArClearInterruptFlag();
|
||||
KeAcquireSpinLock(&KepSystemResourcesLock);
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Iterate through system resources list */
|
||||
ListEntry = KepSystemResourcesListHead.Flink;
|
||||
while(ListEntry != &KepSystemResourcesListHead)
|
||||
ListEntry = ResourcesListHead.Flink;
|
||||
while(ListEntry != &ResourcesListHead)
|
||||
{
|
||||
/* Get resource header */
|
||||
Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
|
||||
@@ -151,19 +106,19 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
}
|
||||
|
||||
/* Check if resource was found */
|
||||
if(ListEntry == &KepSystemResourcesListHead)
|
||||
if(ListEntry == &ResourcesListHead)
|
||||
{
|
||||
/* Resource not found, return NULL */
|
||||
Resource = NULL;
|
||||
Resource = nullptr;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Release spinlock and re-enable interrupts if necessary */
|
||||
KeReleaseSpinLock(&KepSystemResourcesLock);
|
||||
SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
ArSetInterruptFlag();
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/* Return resource header and status code */
|
||||
@@ -171,6 +126,28 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.
|
||||
*
|
||||
* @param ResourceType
|
||||
* Supplies system resource type.
|
||||
*
|
||||
* @param ResourceHeader
|
||||
* Specifies a memory area where a pointer to the system resource header will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
|
||||
{
|
||||
/* Get system resource without acquiring an ownership */
|
||||
return GetSystemResource(ResourceType, FALSE, ResourceHeader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes system resource management.
|
||||
*
|
||||
@@ -180,22 +157,22 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepInitializeSystemResources(VOID)
|
||||
SystemResources::InitializeResources(VOID)
|
||||
{
|
||||
PSYSTEM_RESOURCE_HEADER ResourceHeader;
|
||||
PLIST_ENTRY ListEntry, NextListEntry;
|
||||
ULONG ResourceSize;
|
||||
|
||||
/* Initialize system resources spin lock and resource list */
|
||||
KeInitializeSpinLock(&KepSystemResourcesLock);
|
||||
RtlInitializeListHead(&KepSystemResourcesListHead);
|
||||
SpinLock::InitializeSpinLock(&ResourcesLock);
|
||||
RtlInitializeListHead(&ResourcesListHead);
|
||||
|
||||
/* Make sure there are some system resources available */
|
||||
if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead))
|
||||
if(!RtlListEmpty(BootInformation::GetSystemResources()))
|
||||
{
|
||||
/* Iterate through system resources list */
|
||||
ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink;
|
||||
while(ListEntry != &KeInitializationBlock->SystemResourcesListHead)
|
||||
ListEntry = BootInformation::GetSystemResources()->Flink;
|
||||
while(ListEntry != BootInformation::GetSystemResources())
|
||||
{
|
||||
/* Get resource header and next list entry */
|
||||
ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
|
||||
@@ -223,7 +200,7 @@ KepInitializeSystemResources(VOID)
|
||||
{
|
||||
/* Move valid resource to the internal kernel list of system resources */
|
||||
RtlRemoveEntryList(&ResourceHeader->ListEntry);
|
||||
RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry);
|
||||
RtlInsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry);
|
||||
}
|
||||
|
||||
/* Go to the next list entry */
|
||||
@@ -231,3 +208,31 @@ KepInitializeSystemResources(VOID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases boot system resource.
|
||||
*
|
||||
* @param ResourceHeader
|
||||
* Specifies a pointer to the boot system resource header.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
{
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Release resource lock */
|
||||
ResourceHeader->ResourceLocked = FALSE;
|
||||
|
||||
/* Release spinlock and enable interrupts */
|
||||
SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
}
|
||||
|
||||
} /* namespace */
|
@@ -1,14 +1,17 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/ke/timer.c
|
||||
* FILE: xtoskrnl/ke/timer.cc
|
||||
* DESCRIPTION: Kernel timer object support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtos.h>
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
namespace KE
|
||||
{
|
||||
|
||||
/**
|
||||
* Cancels the timer.
|
||||
*
|
||||
@@ -21,7 +24,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
KeCancelTimer(IN PKTIMER Timer)
|
||||
Timer::CancelTimer(IN PKTIMER Timer)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
KRUNLEVEL RunLevel;
|
||||
@@ -31,19 +34,19 @@ KeCancelTimer(IN PKTIMER Timer)
|
||||
|
||||
/* Raise run level and acquire dispatcher lock */
|
||||
RunLevel = KeRaiseRunLevel(SYNC_LEVEL);
|
||||
KeAcquireQueuedSpinLock(DispatcherLock);
|
||||
SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
|
||||
/* Check timer status */
|
||||
if(Timer->Header.Inserted)
|
||||
{
|
||||
/* Remove the timer from the list */
|
||||
KepRemoveTimer(Timer);
|
||||
RemoveTimer(Timer);
|
||||
Result = TRUE;
|
||||
}
|
||||
|
||||
/* Release dispatcher lock and process the deferred ready list */
|
||||
KeReleaseQueuedSpinLock(DispatcherLock);
|
||||
KepExitDispatcher(RunLevel);
|
||||
SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KThread::ExitDispatcher(RunLevel);
|
||||
|
||||
/* Return result */
|
||||
return Result;
|
||||
@@ -61,7 +64,7 @@ KeCancelTimer(IN PKTIMER Timer)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeClearTimer(IN PKTIMER Timer)
|
||||
Timer::ClearTimer(IN PKTIMER Timer)
|
||||
{
|
||||
/* Clear signal state */
|
||||
Timer->Header.SignalState = 0;
|
||||
@@ -79,7 +82,7 @@ KeClearTimer(IN PKTIMER Timer)
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
KeGetTimerState(IN PKTIMER Timer)
|
||||
Timer::GetState(IN PKTIMER Timer)
|
||||
{
|
||||
/* Return timer state */
|
||||
return (BOOLEAN)Timer->Header.SignalState;
|
||||
@@ -100,11 +103,11 @@ KeGetTimerState(IN PKTIMER Timer)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeInitializeTimer(OUT PKTIMER Timer,
|
||||
IN KTIMER_TYPE Type)
|
||||
Timer::InitializeTimer(OUT PKTIMER Timer,
|
||||
IN KTIMER_TYPE Type)
|
||||
{
|
||||
/* Initialize the header */
|
||||
Timer->Header.Type = TimerNotificationObject + Type;
|
||||
Timer->Header.Type = TimerNotificationObject + (UCHAR)Type;
|
||||
Timer->Header.Inserted = 0;
|
||||
Timer->Header.SignalState = 0;
|
||||
|
||||
@@ -129,7 +132,7 @@ KeInitializeTimer(OUT PKTIMER Timer,
|
||||
*/
|
||||
XTAPI
|
||||
ULONGLONG
|
||||
KeQueryTimer(IN PKTIMER Timer)
|
||||
Timer::QueryTimer(IN PKTIMER Timer)
|
||||
{
|
||||
KRUNLEVEL RunLevel;
|
||||
ULONGLONG DueTime;
|
||||
@@ -139,7 +142,7 @@ KeQueryTimer(IN PKTIMER Timer)
|
||||
|
||||
/* Raise run level and acquire dispatcher lock */
|
||||
RunLevel = KeRaiseRunLevel(SYNC_LEVEL);
|
||||
KeAcquireQueuedSpinLock(DispatcherLock);
|
||||
SpinLock::AcquireQueuedSpinLock(DispatcherLock);
|
||||
|
||||
/* Check timer status */
|
||||
if(Timer->Header.Inserted)
|
||||
@@ -149,8 +152,8 @@ KeQueryTimer(IN PKTIMER Timer)
|
||||
}
|
||||
|
||||
/* Release dispatcher lock and process the deferred ready list */
|
||||
KeReleaseQueuedSpinLock(DispatcherLock);
|
||||
KepExitDispatcher(RunLevel);
|
||||
SpinLock::ReleaseQueuedSpinLock(DispatcherLock);
|
||||
KThread::ExitDispatcher(RunLevel);
|
||||
|
||||
/* Return timer's due time */
|
||||
return DueTime;
|
||||
@@ -177,10 +180,10 @@ KeQueryTimer(IN PKTIMER Timer)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KeSetTimer(IN PKTIMER Timer,
|
||||
IN LARGE_INTEGER DueTime,
|
||||
IN LONG Period,
|
||||
IN PKDPC Dpc)
|
||||
Timer::SetTimer(IN PKTIMER Timer,
|
||||
IN LARGE_INTEGER DueTime,
|
||||
IN LONG Period,
|
||||
IN PKDPC Dpc)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
@@ -197,9 +200,11 @@ KeSetTimer(IN PKTIMER Timer,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KepRemoveTimer(IN OUT PKTIMER Timer)
|
||||
Timer::RemoveTimer(IN OUT PKTIMER Timer)
|
||||
{
|
||||
/* Remove the timer from the list */
|
||||
Timer->Header.Inserted = FALSE;
|
||||
RtlRemoveEntryList(&Timer->TimerListEntry);
|
||||
}
|
||||
|
||||
} /* namespace */
|
Reference in New Issue
Block a user