Compare commits

8 Commits

Author SHA1 Message Date
17712883c5 Include new KE headers
Some checks failed
Builds / ExectOS (amd64, release) (push) Failing after 20s
Builds / ExectOS (amd64, debug) (push) Failing after 27s
Builds / ExectOS (i686, release) (push) Failing after 25s
Builds / ExectOS (i686, debug) (push) Failing after 20s
2025-09-09 23:24:43 +02:00
5cb6474ade Sync CMakeLists with source tree
Some checks failed
Builds / ExectOS (amd64, release) (push) Failing after 28s
Builds / ExectOS (amd64, debug) (push) Failing after 19s
Builds / ExectOS (i686, debug) (push) Failing after 19s
Builds / ExectOS (i686, release) (push) Failing after 25s
2025-09-09 23:22:37 +02:00
4947f788d5 Migrate KE subsystem to C++
Some checks failed
Builds / ExectOS (amd64, debug) (push) Failing after 23s
Builds / ExectOS (amd64, release) (push) Failing after 27s
Builds / ExectOS (i686, debug) (push) Failing after 21s
Builds / ExectOS (i686, release) (push) Failing after 25s
2025-09-09 23:20:50 +02:00
465a23633e Sync CMakeLists with current source tree
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 32s
Builds / ExectOS (amd64, debug) (push) Successful in 35s
Builds / ExectOS (i686, debug) (push) Successful in 32s
Builds / ExectOS (i686, release) (push) Successful in 30s
2025-09-08 22:39:07 +02:00
7c5d6326f8 Migrate EX subsystem to C++
Some checks failed
Builds / ExectOS (amd64, release) (push) Failing after 23s
Builds / ExectOS (i686, debug) (push) Failing after 23s
Builds / ExectOS (amd64, debug) (push) Failing after 25s
Builds / ExectOS (i686, release) (push) Failing after 23s
2025-09-08 22:35:59 +02:00
3f5f57ef12 Remove leftover test code
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 28s
Builds / ExectOS (amd64, release) (push) Successful in 24s
Builds / ExectOS (amd64, debug) (push) Successful in 34s
Builds / ExectOS (i686, debug) (push) Successful in 33s
2025-09-08 15:44:12 +02:00
4e24b239a4 Fix cmake source path
Some checks failed
Builds / ExectOS (amd64, debug) (push) Failing after 27s
Builds / ExectOS (amd64, release) (push) Failing after 25s
Builds / ExectOS (i686, release) (push) Successful in 28s
Builds / ExectOS (i686, debug) (push) Successful in 30s
2025-09-08 15:40:26 +02:00
c8dc2a1407 Migrate AR subsystem to C++
Some checks failed
Builds / ExectOS (amd64, debug) (push) Failing after 24s
Builds / ExectOS (amd64, release) (push) Failing after 27s
Builds / ExectOS (i686, debug) (push) Failing after 24s
Builds / ExectOS (i686, release) (push) Failing after 24s
2025-09-08 15:29:13 +02:00
91 changed files with 4373 additions and 1403 deletions

View File

@@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_STANDARD 23)
# Disable standard C libraries
# Disable standard C and C++ libraries
set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "")
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "")
# Clean linker flags
set(CMAKE_STATIC_LINKER_FLAGS "")

View File

@@ -1,13 +0,0 @@
## XT Building Kit (XTBK)
The XTBK, or XT Building Kit is a kind of SDK (Software Development Kit) utilized internally by XTOS, the XT Operating
System. It is designed to provide a collection of public functions that are available within the operating system but
not necessarily exposed or accessible to software and driver developers.
Unlike XTDK, which focuses on providing headers for external developers to create kernel mode drivers and user mode
applications, XTBK serves as an extension to XTDK and aids in the code-sharing process between different XTOS
components. This enables the reuse of code across various components of the operating system, resulting in a more
efficient and streamlined development process.
By incorporating XTBK, XTOS can optimize code reuse, particularly in low-level kernel code that can be shared with other
components like the boot loader. This approach helps in reducing code duplication and improving overall code
maintainability. Additionally, it allows for consistent implementation of functionality across different parts of the OS.

View File

@@ -16,30 +16,37 @@
/* Routines used by XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL
VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL
VOID
ArHalt(VOID);
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */
XTCLINK
XTCDECL
UCHAR
HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL
ULONG
HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL
USHORT
HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL
VOID
HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data);
XTCLINK
XTCDECL
VOID
HlIoPortOutLong(IN USHORT Port,
IN ULONG Value);
XTCLINK
XTCDECL
VOID
HlIoPortOutShort(IN USHORT Port,

View File

@@ -14,6 +14,7 @@
/* XT BootLoader routines forward references */
XTCLINK
XTCDECL
EFI_STATUS
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,

View File

@@ -14,26 +14,32 @@
/* Kernel Executive routines forward references */
XTCLINK
XTFASTCALL
BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL
VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL
VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL
VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL
VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
XTCLINK
XTFASTCALL
VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);

View File

@@ -15,11 +15,13 @@
/* Routines used by XTLDR */
XTCLINK
XTCDECL
XTSTATUS
HlComPortPutByte(IN PCPPORT Port,
IN UCHAR Byte);
XTCLINK
XTCDECL
XTSTATUS
HlInitializeComPort(IN OUT PCPPORT Port,

View File

@@ -16,26 +16,32 @@
/* Routines used by XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL
VOID
ArHalt(VOID);
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,

View File

@@ -16,28 +16,34 @@
/* HAL library routines forward references */
XTCLINK
XTCDECL
UCHAR
HlIoPortInByte(IN USHORT Port);
XTCLINK
XTCDECL
ULONG
HlIoPortInLong(IN USHORT Port);
XTCLINK
XTCDECL
USHORT
HlIoPortInShort(IN USHORT Port);
XTCLINK
XTCDECL
VOID
HlIoPortOutByte(IN USHORT Port,
IN UCHAR Data);
XTCLINK
XTCDECL
VOID
HlIoPortOutLong(IN USHORT Port,
IN ULONG Value);
XTCLINK
XTCDECL
VOID
HlIoPortOutShort(IN USHORT Port,

View File

@@ -16,36 +16,44 @@
/* Kernel services routines forward references */
XTCLINK
XTFASTCALL
VOID
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL
VOID
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI
XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI
BOOLEAN
KeCancelTimer(IN PKTIMER Timer);
XTCLINK
XTFASTCALL
KRUNLEVEL
KeGetCurrentRunLevel(VOID);
XTCLINK
XTAPI
XTSTATUS
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
XTCLINK
XTAPI
BOOLEAN
KeGetTimerState(IN PKTIMER Timer);
XTCLINK
XTAPI
VOID
KeInitializeApc(IN PKAPC Apc,
@@ -57,45 +65,54 @@ KeInitializeApc(IN PKAPC Apc,
IN KPROCESSOR_MODE ApcMode,
IN PVOID Context);
XTCLINK
XTAPI
VOID
KeInitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext);
XTCLINK
XTAPI
VOID
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count,
IN LONG Limit);
XTCLINK
XTAPI
VOID
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI
VOID
KeInitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext);
XTCLINK
XTAPI
VOID
KeInitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type);
XTCLINK
XTFASTCALL
VOID
KeLowerRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTFASTCALL
KRUNLEVEL
KeRaiseRunLevel(IN KRUNLEVEL RunLevel);
XTCLINK
XTAPI
LONG
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore);
XTCLINK
XTAPI
LONG
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
@@ -103,23 +120,28 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Adjustment,
IN BOOLEAN Wait);
XTCLINK
XTFASTCALL
VOID
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
XTCLINK
XTFASTCALL
VOID
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
XTCLINK
XTAPI
VOID
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);
XTCLINK
XTAPI
VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number);
XTCLINK
XTAPI
VOID
KeSetTimer(IN PKTIMER Timer,
@@ -127,10 +149,12 @@ KeSetTimer(IN PKTIMER Timer,
IN LONG Period,
IN PKDPC Dpc);
XTCLINK
XTAPI
VOID
KeSignalCallDpcDone(IN PVOID SystemArgument);
XTCLINK
XTAPI
BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument);

View File

@@ -7,6 +7,7 @@
*/
/* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h>
#include <xtstatus.h>
#include <xttarget.h>

21
sdk/xtdk/xtcompat.h Normal file
View File

@@ -0,0 +1,21 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: sdk/xtdk/xtcompat.h
* DESCRIPTION: C/C++ compatibility macros
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTDK_XTCOMPAT_H
#define __XTDK_XTCOMPAT_H
#ifdef __cplusplus
#define XTCLINK extern "C"
typedef wchar_t wchar;
#else
#define XTCLINK
typedef unsigned short wchar;
#endif
#endif /* __XTDK_XTCOMPAT_H */

View File

@@ -7,6 +7,7 @@
*/
/* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h>
#include <xtstatus.h>
#include <xttarget.h>

View File

@@ -52,6 +52,7 @@ typedef enum _LOADER_MEMORY_TYPE LOADER_MEMORY_TYPE, *PLOADER_MEMORY_TYPE;
typedef enum _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;
typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
/* Structures forward references */

View File

@@ -10,6 +10,7 @@
#define __XTDK_XTTYPES_H
#include <xttarget.h>
#include <xtcompat.h>
/* Standard C types */
@@ -128,7 +129,7 @@ typedef CHAR SZ, *PSZ;
typedef const CHAR CSZ, *PCSZ;
/* UNICODE character types */
typedef USHORT WCHAR, *PWCHAR;
typedef wchar WCHAR, *PWCHAR;
typedef WCHAR *PWCH, *LPWCH;
typedef const WCHAR *PCWCH, *LPCWCH;
typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR;

View File

@@ -10,7 +10,7 @@ include_directories(
# Specify list of library source code files
list(APPEND LIBXTOS_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/rtl/globals.c
@@ -25,11 +25,12 @@ list(APPEND LIBXTOS_SOURCE
list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c
${XTOSKRNL_SOURCE_DIR}/ex/rundown.c
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc
${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.c
${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c
@@ -42,25 +43,26 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c
${XTOSKRNL_SOURCE_DIR}/kd/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/apc.c
${XTOSKRNL_SOURCE_DIR}/ke/dpc.c
${XTOSKRNL_SOURCE_DIR}/ke/event.c
${XTOSKRNL_SOURCE_DIR}/ke/globals.c
${XTOSKRNL_SOURCE_DIR}/ke/info.c
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.c
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.c
${XTOSKRNL_SOURCE_DIR}/ke/kthread.c
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.c
${XTOSKRNL_SOURCE_DIR}/ke/panic.c
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.c
${XTOSKRNL_SOURCE_DIR}/ke/semphore.c
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.c
${XTOSKRNL_SOURCE_DIR}/ke/sysres.c
${XTOSKRNL_SOURCE_DIR}/ke/timer.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irqs.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.c
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
${XTOSKRNL_SOURCE_DIR}/ke/apc.cc
${XTOSKRNL_SOURCE_DIR}/ke/bootinfo.cc
${XTOSKRNL_SOURCE_DIR}/ke/crash.cc
${XTOSKRNL_SOURCE_DIR}/ke/data.cc
${XTOSKRNL_SOURCE_DIR}/ke/dpc.cc
${XTOSKRNL_SOURCE_DIR}/ke/event.cc
${XTOSKRNL_SOURCE_DIR}/ke/exports.cc
${XTOSKRNL_SOURCE_DIR}/ke/kprocess.cc
${XTOSKRNL_SOURCE_DIR}/ke/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/kthread.cc
${XTOSKRNL_SOURCE_DIR}/ke/kubsan.cc
${XTOSKRNL_SOURCE_DIR}/ke/runlevel.cc
${XTOSKRNL_SOURCE_DIR}/ke/semphore.cc
${XTOSKRNL_SOURCE_DIR}/ke/spinlock.cc
${XTOSKRNL_SOURCE_DIR}/ke/sysres.cc
${XTOSKRNL_SOURCE_DIR}/ke/timer.cc
${XTOSKRNL_SOURCE_DIR}/mm/globals.c
${XTOSKRNL_SOURCE_DIR}/mm/hlpool.c
${XTOSKRNL_SOURCE_DIR}/mm/init.c

View File

@@ -22,9 +22,9 @@
*
* @since XT 1.0
*/
.macro ArpCreateTrapHandler Vector
.global ArpTrap\Vector
ArpTrap\Vector:
.macro ArCreateTrapHandler Vector
.global ArTrap\Vector
ArTrap\Vector:
/* Push fake error code for non-error vectors */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0
@@ -113,7 +113,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
mov %rsp, %rcx
cld
call ArpDispatchTrap
call ArDispatchTrap
/* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%rbp)
@@ -176,6 +176,6 @@ KernelModeReturn$\Vector:
/* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArpCreateTrapHandler 0x\i\j
ArCreateTrapHandler 0x\i\j
.endr
.endr

View File

@@ -1,15 +1,19 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/cpufunc.c
* FILE: xtoskrnl/ar/amd64/cpufunc.cc
* DESCRIPTION: Routines to provide access to special AMD64 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/**
/* Architecture-specific Library */
namespace AR
{
/**
* Instructs the processor to clear the interrupt flag.
*
* @return This routine does not return any value.
@@ -18,7 +22,7 @@
*/
XTCDECL
VOID
ArClearInterruptFlag(VOID)
CpuFunc::ClearInterruptFlag(VOID)
{
__asm__ volatile("cli");
}
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{
UINT32 MaxLeaf;
@@ -76,10 +80,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/
XTCDECL
VOID
ArFlushTlb(VOID)
CpuFunc::FlushTlb(VOID)
{
/* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3));
WriteControlRegister(3, ReadControlRegister(3));
}
/**
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/
XTCDECL
ULONG
ArGetCpuFlags(VOID)
CpuFunc::GetCpuFlags(VOID)
{
ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY
XTCDECL
ULONG_PTR
ArGetStackPointer(VOID)
CpuFunc::GetStackPointer(VOID)
{
/* Get current stack pointer */
__asm__ volatile("movq %%rsp, %%rax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/
XTCDECL
VOID
ArHalt(VOID)
CpuFunc::Halt(VOID)
{
__asm__ volatile("hlt");
}
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
CpuFunc::InterruptsEnabled(VOID)
{
ULONG_PTR Flags;
/* Get RFLAGS register */
Flags = ArGetCpuFlags();
Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/
XTCDECL
VOID
ArInvalidateTlbEntry(IN PVOID Address)
CpuFunc::InvalidateTlbEntry(IN PVOID Address)
{
__asm__ volatile("invlpg (%0)"
:
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(IN PVOID Address)
*/
XTCDECL
VOID
ArLoadGlobalDescriptorTable(IN PVOID Source)
CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{
__asm__ volatile("lgdt %0"
:
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/
XTCDECL
VOID
ArLoadInterruptDescriptorTable(IN PVOID Source)
CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{
__asm__ volatile("lidt %0"
:
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/
XTCDECL
VOID
ArLoadLocalDescriptorTable(IN USHORT Source)
CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{
__asm__ volatile("lldtw %0"
:
@@ -251,7 +255,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/
XTCDECL
VOID
ArLoadMxcsrRegister(IN ULONG Source)
CpuFunc::LoadMxcsrRegister(IN ULONG Source)
{
__asm__ volatile("ldmxcsr %0"
:
@@ -273,8 +277,8 @@ ArLoadMxcsrRegister(IN ULONG Source)
*/
XTCDECL
VOID
ArLoadSegment(IN USHORT Segment,
IN ULONG Source)
CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source)
{
switch(Segment)
{
@@ -335,7 +339,7 @@ ArLoadSegment(IN USHORT Segment,
*/
XTCDECL
VOID
ArLoadTaskRegister(USHORT Source)
CpuFunc::LoadTaskRegister(USHORT Source)
{
__asm__ volatile("ltr %0"
:
@@ -351,7 +355,7 @@ ArLoadTaskRegister(USHORT Source)
*/
XTCDECL
VOID
ArMemoryBarrier(VOID)
CpuFunc::MemoryBarrier(VOID)
{
LONG Barrier;
__asm__ volatile("lock; orl $0, %0;"
@@ -371,7 +375,7 @@ ArMemoryBarrier(VOID)
*/
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{
ULONG_PTR Value;
@@ -435,7 +439,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{
ULONG_PTR Value;
@@ -504,7 +508,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/
XTCDECL
ULONGLONG
ArReadGSQuadWord(ULONG Offset)
CpuFunc::ReadGSQuadWord(ULONG Offset)
{
ULONGLONG Value;
@@ -527,7 +531,7 @@ ArReadGSQuadWord(ULONG Offset)
*/
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{
ULONG Low, High;
@@ -548,7 +552,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
CpuFunc::ReadMxCsrRegister(VOID)
{
return __builtin_ia32_stmxcsr();
}
@@ -562,7 +566,7 @@ ArReadMxCsrRegister(VOID)
*/
XTCDECL
ULONGLONG
ArReadTimeStampCounter(VOID)
CpuFunc::ReadTimeStampCounter(VOID)
{
ULONGLONG Low, High;
@@ -582,7 +586,7 @@ ArReadTimeStampCounter(VOID)
*/
XTCDECL
VOID
ArReadWriteBarrier(VOID)
CpuFunc::ReadWriteBarrier(VOID)
{
__asm__ volatile(""
:
@@ -599,7 +603,7 @@ ArReadWriteBarrier(VOID)
*/
XTCDECL
VOID
ArSetInterruptFlag(VOID)
CpuFunc::SetInterruptFlag(VOID)
{
__asm__ volatile("sti");
}
@@ -616,7 +620,7 @@ ArSetInterruptFlag(VOID)
*/
XTCDECL
VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination)
@@ -636,7 +640,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination)
@@ -656,7 +660,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination)
@@ -679,8 +683,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreSegment(IN USHORT Segment,
OUT PVOID Destination)
CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination)
{
switch(Segment)
{
@@ -726,7 +730,7 @@ ArStoreSegment(IN USHORT Segment,
*/
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{
__asm__ volatile("str %0"
: "=m" (*(PULONG)Destination)
@@ -749,8 +753,8 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
/* Write a value into specified control register */
switch(ControlRegister)
@@ -808,8 +812,8 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/
XTCDECL
VOID
ArWriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
{
/* Write a value into specified debug register */
switch(DebugRegister)
@@ -820,48 +824,56 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
:
: "r" (Value)
: "memory");
break;
case 1:
/* Write value to DR1 */
__asm__ volatile("mov %0, %%dr1"
:
: "r" (Value)
: "memory");
break;
case 2:
/* Write value to DR2 */
__asm__ volatile("mov %0, %%dr2"
:
: "r" (Value)
: "memory");
break;
case 3:
/* Write value to DR3 */
__asm__ volatile("mov %0, %%dr3"
:
: "r" (Value)
: "memory");
break;
case 4:
/* Write value to DR4 */
__asm__ volatile("mov %0, %%dr4"
:
: "r" (Value)
: "memory");
break;
case 5:
/* Write value to DR5 */
__asm__ volatile("mov %0, %%dr5"
:
: "r" (Value)
: "memory");
break;
case 6:
/* Write value to DR6 */
__asm__ volatile("mov %0, %%dr6"
:
: "r" (Value)
: "memory");
break;
case 7:
/* Write value to DR7 */
__asm__ volatile("mov %0, %%dr7"
:
: "r" (Value)
: "memory");
break;
}
}
@@ -877,7 +889,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/
XTCDECL
VOID
ArWriteEflagsRegister(IN UINT_PTR Value)
CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{
__asm__ volatile("push %0\n"
"popf"
@@ -900,8 +912,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
ULONG Low = Value & 0xFFFFFFFF;
ULONG High = Value >> 32;
@@ -922,10 +934,187 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/
XTCDECL
VOID
ArYieldProcessor(VOID)
CpuFunc::YieldProcessor(VOID)
{
__asm__ volatile("pause"
:
:
: "memory");
}
} /* namespace */
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
AR::CpuFunc::ClearInterruptFlag();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
return AR::CpuFunc::CpuId(Registers);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArHalt(VOID)
{
AR::CpuFunc::Halt();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
return AR::CpuFunc::ReadControlRegister(ControlRegister);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
return AR::CpuFunc::ReadModelSpecificRegister(Register);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
AR::CpuFunc::WriteControlRegister(ControlRegister, Value);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArYieldProcessor(VOID)
{
AR::CpuFunc::YieldProcessor();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
AR::CpuFunc::ReadWriteBarrier();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
{
return AR::CpuFunc::InterruptsEnabled();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
AR::CpuFunc::SetInterruptFlag();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONGLONG
ArReadGSQuadWord(ULONG Offset)
{
return AR::CpuFunc::ReadGSQuadWord(Offset);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
return AR::CpuFunc::ReadDebugRegister(DebugRegister);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return AR::CpuFunc::ReadMxCsrRegister();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreGlobalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreGlobalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreInterruptDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreInterruptDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreLocalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreLocalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
AR::CpuFunc::StoreTaskRegister(Destination);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArFlushTlb(VOID)
{
AR::CpuFunc::FlushTlb();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
AR::CpuFunc::WriteModelSpecificRegister(Register, Value);
}

34
xtoskrnl/ar/amd64/data.cc Normal file
View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/data.cc
* DESCRIPTION: AMD64 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
} /* namespace */

View File

@@ -1,28 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,121 +1,28 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/procsup.c
* FILE: xtoskrnl/ar/amd64/procsup.cc
* DESCRIPTION: AMD64 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Initializes AMD64 processor specific structures.
* Gets the base address of the kernel boot stack.
*
* @return This routine does not return any value.
* @return This routine returns a pointer to the kernel boot stack.
*
* @since XT 1.0
*/
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
PVOID ProcSup::GetBootStack(VOID)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = ArInitialIdt;
}
else
{
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelBootStack = &ArKernelBootStack;
KernelFaultStack = &ArKernelFaultStack;
ProcessorBlock = &ArInitialProcessorBlock;
}
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Set GS base */
ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
return (PVOID)BootStack;
}
/**
@@ -128,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/
XTAPI
VOID
ArpIdentifyProcessor(VOID)
ProcSup::IdentifyProcessor(VOID)
{
PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters;
@@ -143,10 +50,10 @@ ArpIdentifyProcessor(VOID)
/* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters);
CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx;
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -155,7 +62,7 @@ ArpIdentifyProcessor(VOID)
/* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
ArCpuId(&CpuRegisters);
CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -195,6 +102,81 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */
}
/**
* Initializes AMD64 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Set GS base */
CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/**
* Initializes the kernel's Global Descriptor Table (GDT).
*
@@ -207,19 +189,21 @@ ArpIdentifyProcessor(VOID)
*/
XTAPI
VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
/* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase,
sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase,
(GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
}
/**
@@ -234,7 +218,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/
XTAPI
VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
UINT Vector;
@@ -242,34 +226,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0xE1, ArpTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
}
/**
@@ -293,18 +277,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/
XTAPI
VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
{
/* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = (PVOID)Gdt;
ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss;
ProcessorBlock->Prcb.RspBase = Tss->Rsp0;
@@ -322,10 +306,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL;
ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial MXCSR register value */
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
@@ -343,56 +327,50 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/
XTAPI
VOID
ArpInitializeProcessorRegisters(VOID)
ProcSup::InitializeProcessorRegisters(VOID)
{
ULONGLONG PatAttributes;
/* Enable FXSAVE restore */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR);
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT);
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE);
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
/* Enable large pages */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE);
CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP);
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
/* Set alignment mask */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM);
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP);
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE);
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */
ArFlushTlb();
/* Initialize system calls MSR */
ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
ArWriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&ArpHandleSystemCall32);
ArWriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&ArpHandleSystemCall64);
ArWriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
CpuFunc::FlushTlb();
/* Initialize system call MSRs */
Traps::InitializeSystemCallMsrs();
/* Enable No-Execute (NXE) in EFER MSR */
ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
/* Initialize Page Attribute Table */
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
ArWriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */
ArLoadMxcsrRegister(INITIAL_MXCSR);
CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
}
/**
@@ -422,12 +400,12 @@ ArpInitializeProcessorRegisters(VOID)
*/
XTAPI
VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
{
UINT_PTR Address;
@@ -442,15 +420,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */
*Gdt = (PVOID)Address;
Address += sizeof(ArInitialGdt);
*Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(InitialGdt);
/* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address;
Address += sizeof(ArInitialProcessorBlock);
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PVOID)Address;
*Tss = (PKTSS)(PVOID)Address;
}
/**
@@ -462,15 +440,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/
XTAPI
VOID
ArpInitializeSegments(VOID)
ProcSup::InitializeSegments(VOID)
{
/* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA);
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
}
/**
@@ -488,9 +466,9 @@ ArpInitializeSegments(VOID)
*/
XTAPI
VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
{
/* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
@@ -532,13 +510,13 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/
XTAPI
VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
{
PKGDTENTRY GdtEntry;
UCHAR Granularity;
@@ -580,6 +558,40 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->MustBeZero = 0;
}
/**
* Updates an existing AMD64 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
GdtEntry->BaseUpper = (Base >> 32);
}
/**
* Fills in a call, interrupt, task or trap gate entry.
*
@@ -607,12 +619,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/
XTAPI
VOID
ArpSetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
{
/* Setup the gate */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
@@ -624,3 +636,24 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
}
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/traps.c
* FILE: xtoskrnl/ar/amd64/traps.cc
* DESCRIPTION: AMD64 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Dispatches the trap provided by common trap handler.
*
@@ -21,124 +25,138 @@
*/
XTCDECL
VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
/* Check vector and call appropriate handler */
switch(TrapFrame->Vector)
{
case 0x00:
/* Divide By Zero exception */
ArpHandleTrap00(TrapFrame);
HandleTrap00(TrapFrame);
break;
case 0x01:
/* Debug exception */
ArpHandleTrap01(TrapFrame);
HandleTrap01(TrapFrame);
break;
case 0x02:
/* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame);
HandleTrap02(TrapFrame);
break;
case 0x03:
/* INT3 instruction executed */
ArpHandleTrap03(TrapFrame);
HandleTrap03(TrapFrame);
break;
case 0x04:
/* Overflow exception */
ArpHandleTrap04(TrapFrame);
HandleTrap04(TrapFrame);
break;
case 0x05:
/* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame);
HandleTrap05(TrapFrame);
break;
case 0x06:
/* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame);
HandleTrap06(TrapFrame);
break;
case 0x07:
/* Device Not Available exception */
ArpHandleTrap07(TrapFrame);
HandleTrap07(TrapFrame);
break;
case 0x08:
/* Double Fault exception */
ArpHandleTrap08(TrapFrame);
HandleTrap08(TrapFrame);
break;
case 0x09:
/* Segment Overrun exception */
ArpHandleTrap09(TrapFrame);
HandleTrap09(TrapFrame);
break;
case 0x0A:
/* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame);
HandleTrap0A(TrapFrame);
break;
case 0x0B:
/* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame);
HandleTrap0B(TrapFrame);
break;
case 0x0C:
/* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame);
HandleTrap0C(TrapFrame);
break;
case 0x0D:
/* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame);
HandleTrap0D(TrapFrame);
break;
case 0x0E:
/* Page Fault exception */
ArpHandleTrap0E(TrapFrame);
HandleTrap0E(TrapFrame);
break;
case 0x10:
/* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame);
HandleTrap10(TrapFrame);
break;
case 0x11:
/* Alignment Check exception */
ArpHandleTrap11(TrapFrame);
HandleTrap11(TrapFrame);
break;
case 0x12:
/* Machine Check exception */
ArpHandleTrap12(TrapFrame);
HandleTrap12(TrapFrame);
break;
case 0x13:
/* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame);
HandleTrap13(TrapFrame);
break;
case 0x1F:
/* Software Interrupt at APC level */
ArpHandleTrap1F(TrapFrame);
HandleTrap1F(TrapFrame);
break;
case 0x2C:
/* Assertion raised */
ArpHandleTrap2C(TrapFrame);
HandleTrap2C(TrapFrame);
break;
case 0x2D:
/* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame);
HandleTrap2D(TrapFrame);
break;
case 0x2F:
/* Software Interrupt at DISPATCH level */
ArpHandleTrap2F(TrapFrame);
HandleTrap2F(TrapFrame);
break;
case 0xE1:
/* InterProcessor Interrupt (IPI) */
ArpHandleTrapE1(TrapFrame);
HandleTrapE1(TrapFrame);
break;
default:
/* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame);
HandleTrapFF(TrapFrame);
break;
}
}
/**
* Handles a 32-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArpHandleSystemCall32(VOID)
Traps::HandleSystemCall32(VOID)
{
DebugPrint(L"Handled 32-bit system call!\n");
}
/**
* Handles a 64-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
ArpHandleSystemCall64(VOID)
Traps::HandleSystemCall64(VOID)
{
DebugPrint(L"Handled 64-bit system call!\n");
}
@@ -155,7 +173,7 @@ ArpHandleSystemCall64(VOID)
*/
XTCDECL
VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;);
@@ -173,7 +191,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;);
@@ -191,7 +209,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;);
@@ -209,7 +227,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;);
@@ -227,7 +245,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;);
@@ -245,7 +263,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;);
@@ -263,7 +281,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;);
@@ -281,7 +299,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;);
@@ -299,7 +317,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;);
@@ -317,7 +335,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;);
@@ -335,7 +353,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;);
@@ -353,7 +371,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;);
@@ -371,7 +389,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;);
@@ -389,7 +407,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;);
@@ -407,7 +425,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;);
@@ -425,7 +443,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;);
@@ -443,7 +461,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;);
@@ -461,7 +479,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;);
@@ -479,7 +497,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;);
@@ -497,7 +515,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n");
}
@@ -514,7 +532,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;);
@@ -532,7 +550,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;);
@@ -550,7 +568,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n");
}
@@ -567,7 +585,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n");
}
@@ -584,8 +602,49 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;);
}
/**
* Initializes system call MSRs.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
Traps::InitializeSystemCallMsrs(VOID)
{
/* Initialize system calls MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
}
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

View File

@@ -22,9 +22,9 @@
*
* @since XT 1.0
*/
.macro ArpCreateTrapHandler Vector
.global _ArpTrap\Vector
_ArpTrap\Vector:
.macro ArCreateTrapHandler Vector
.global _ArTrap\Vector
_ArTrap\Vector:
/* Push fake error code for non-error vectors */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0
@@ -84,7 +84,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp
cld
call _ArpDispatchTrap
call _ArDispatchTrap
/* Clean up the stack */
add $4, %esp
@@ -121,6 +121,6 @@ KernelModeReturn$\Vector:
/* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArpCreateTrapHandler 0x\i\j
ArCreateTrapHandler 0x\i\j
.endr
.endr

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/cpufunc.c
* FILE: xtoskrnl/ar/i686/cpufunc.cc
* DESCRIPTION: Routines to provide access to special i686 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Instructs the processor to clear the interrupt flag.
*
@@ -18,7 +22,7 @@
*/
XTCDECL
VOID
ArClearInterruptFlag(VOID)
CpuFunc::ClearInterruptFlag(VOID)
{
__asm__ volatile("cli");
}
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{
UINT32 MaxLeaf;
@@ -76,7 +80,7 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/
XTCDECL
VOID
ArFlushTlb(VOID)
CpuFunc::FlushTlb(VOID)
{
/* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3));
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/
XTCDECL
ULONG
ArGetCpuFlags(VOID)
CpuFunc::GetCpuFlags(VOID)
{
ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY
XTCDECL
ULONG_PTR
ArGetStackPointer(VOID)
CpuFunc::GetStackPointer(VOID)
{
/* Get current stack pointer */
__asm__ volatile("mov %%esp, %%eax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/
XTCDECL
VOID
ArHalt(VOID)
CpuFunc::Halt(VOID)
{
__asm__ volatile("hlt");
}
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
CpuFunc::InterruptsEnabled(VOID)
{
ULONG_PTR Flags;
/* Get RFLAGS register */
Flags = ArGetCpuFlags();
Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/
XTCDECL
VOID
ArInvalidateTlbEntry(PVOID Address)
CpuFunc::InvalidateTlbEntry(PVOID Address)
{
__asm__ volatile("invlpg (%0)"
:
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(PVOID Address)
*/
XTCDECL
VOID
ArLoadGlobalDescriptorTable(IN PVOID Source)
CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{
__asm__ volatile("lgdt %0"
:
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/
XTCDECL
VOID
ArLoadInterruptDescriptorTable(IN PVOID Source)
CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{
__asm__ volatile("lidt %0"
:
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/
XTCDECL
VOID
ArLoadLocalDescriptorTable(IN USHORT Source)
CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{
__asm__ volatile("lldtw %0"
:
@@ -254,8 +258,8 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/
XTCDECL
VOID
ArLoadSegment(IN USHORT Segment,
IN ULONG Source)
CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source)
{
switch(Segment)
{
@@ -316,7 +320,7 @@ ArLoadSegment(IN USHORT Segment,
*/
XTCDECL
VOID
ArLoadTaskRegister(USHORT Source)
CpuFunc::LoadTaskRegister(USHORT Source)
{
__asm__ volatile("ltr %0"
:
@@ -332,7 +336,7 @@ ArLoadTaskRegister(USHORT Source)
*/
XTCDECL
VOID
ArMemoryBarrier(VOID)
CpuFunc::MemoryBarrier(VOID)
{
LONG Barrier;
__asm__ volatile("xchg %%eax, %0"
@@ -353,7 +357,7 @@ ArMemoryBarrier(VOID)
*/
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{
ULONG_PTR Value;
@@ -410,7 +414,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{
ULONG_PTR Value;
@@ -479,7 +483,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/
XTCDECL
ULONG
ArReadFSDualWord(ULONG Offset)
CpuFunc::ReadFSDualWord(ULONG Offset)
{
ULONG Value;
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
@@ -500,7 +504,7 @@ ArReadFSDualWord(ULONG Offset)
*/
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{
ULONGLONG Value;
@@ -519,7 +523,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
CpuFunc::ReadMxCsrRegister(VOID)
{
return __builtin_ia32_stmxcsr();
}
@@ -533,7 +537,7 @@ ArReadMxCsrRegister(VOID)
*/
XTCDECL
ULONGLONG
ArReadTimeStampCounter(VOID)
CpuFunc::ReadTimeStampCounter(VOID)
{
ULONGLONG Value;
@@ -552,7 +556,7 @@ ArReadTimeStampCounter(VOID)
*/
XTCDECL
VOID
ArReadWriteBarrier(VOID)
CpuFunc::ReadWriteBarrier(VOID)
{
__asm__ volatile(""
:
@@ -569,7 +573,7 @@ ArReadWriteBarrier(VOID)
*/
XTCDECL
VOID
ArSetInterruptFlag(VOID)
CpuFunc::SetInterruptFlag(VOID)
{
__asm__ volatile("sti");
}
@@ -586,7 +590,7 @@ ArSetInterruptFlag(VOID)
*/
XTCDECL
VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination)
@@ -606,7 +610,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination)
@@ -626,7 +630,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination)
CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{
__asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination)
@@ -649,8 +653,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/
XTCDECL
VOID
ArStoreSegment(IN USHORT Segment,
OUT PVOID Destination)
CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination)
{
switch(Segment)
{
@@ -696,7 +700,7 @@ ArStoreSegment(IN USHORT Segment,
*/
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{
__asm__ volatile("str %0"
: "=m" (*(PULONG)Destination)
@@ -719,8 +723,8 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
/* Write a value into specified control register */
switch(ControlRegister)
@@ -771,8 +775,8 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/
XTCDECL
VOID
ArWriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value)
{
/* Write a value into specified debug register */
switch(DebugRegister)
@@ -840,7 +844,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/
XTCDECL
VOID
ArWriteEflagsRegister(IN UINT_PTR Value)
CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{
__asm__ volatile("push %0\n"
"popf"
@@ -863,8 +867,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
__asm__ volatile("wrmsr"
:
@@ -881,10 +885,185 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/
XTCDECL
VOID
ArYieldProcessor(VOID)
CpuFunc::YieldProcessor(VOID)
{
__asm__ volatile("pause"
:
:
: "memory");
}
} /* namespace */
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArClearInterruptFlag(VOID)
{
AR::CpuFunc::ClearInterruptFlag();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers)
{
return AR::CpuFunc::CpuId(Registers);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArHalt(VOID)
{
AR::CpuFunc::Halt();
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister)
{
return AR::CpuFunc::ReadControlRegister(ControlRegister);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register)
{
return AR::CpuFunc::ReadModelSpecificRegister(Register);
}
/* NEEDED BY XTLDR */
XTCLINK
XTCDECL
VOID
ArWriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value)
{
AR::CpuFunc::WriteControlRegister(ControlRegister, Value);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArYieldProcessor(VOID)
{
AR::CpuFunc::YieldProcessor();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArReadWriteBarrier(VOID)
{
AR::CpuFunc::ReadWriteBarrier();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
BOOLEAN
ArInterruptsEnabled(VOID)
{
return AR::CpuFunc::InterruptsEnabled();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArSetInterruptFlag(VOID)
{
AR::CpuFunc::SetInterruptFlag();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG
ArReadFSDualWord(ULONG Offset)
{
return AR::CpuFunc::ReadFSDualWord(Offset);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister)
{
return AR::CpuFunc::ReadDebugRegister(DebugRegister);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
UINT
ArReadMxCsrRegister(VOID)
{
return AR::CpuFunc::ReadMxCsrRegister();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreGlobalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreGlobalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreInterruptDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreInterruptDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreLocalDescriptorTable(IN PVOID Source)
{
AR::CpuFunc::StoreLocalDescriptorTable(Source);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArStoreTaskRegister(OUT PVOID Destination)
{
AR::CpuFunc::StoreTaskRegister(Destination);
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArFlushTlb(VOID)
{
AR::CpuFunc::FlushTlb();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTCDECL
VOID
ArWriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value)
{
AR::CpuFunc::WriteModelSpecificRegister(Register, Value);
}

40
xtoskrnl/ar/i686/data.cc Normal file
View File

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/data.cc
* DESCRIPTION: I686 architecture-specific global and static data
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/* Initial kernel boot stack */
UCHAR ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
/* Double Fault gate */
UCHAR ProcSup::DoubleFaultTss[KTSS_IO_MAPS];
/* Initial kernel fault stack */
UCHAR ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */
KGDTENTRY ProcSup::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */
KIDTENTRY ProcSup::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */
KPROCESSOR_BLOCK ProcSup::InitialProcessorBlock;
/* Initial TSS */
KTSS ProcSup::InitialTss;
/* NMI task gate */
UCHAR ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
} /* namespace */

View File

@@ -1,32 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/globals.c
* DESCRIPTION: XT architecture library global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Initial GDT */
KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0};
/* Initial IDT */
KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0};
/* Initial Processor Block */
KPROCESSOR_BLOCK ArInitialProcessorBlock;
/* Initial TSS */
KTSS ArInitialTss;
/* Double Fault and NMI task gates */
UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS];
UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS];
/* Initial kernel boot stack */
UCHAR ArKernelBootStack[KERNEL_STACK_SIZE] = {0};
/* Initial kernel fault stack */
UCHAR ArKernelFaultStack[KERNEL_STACK_SIZE] = {0};

View File

@@ -1,116 +1,28 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/procsup.c
* FILE: xtoskrnl/ar/i686/procsup.cc
* DESCRIPTION: I686 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Initializes i686 processor specific structures.
* Gets the base address of the kernel boot stack.
*
* @return This routine does not return any value.
* @return This routine returns a pointer to the kernel boot stack.
*
* @since XT 1.0
*/
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
PVOID ProcSup::GetBootStack(VOID)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = ArInitialIdt;
}
else
{
/* Use initial structures */
Gdt = ArInitialGdt;
Idt = ArInitialIdt;
Tss = &ArInitialTss;
KernelBootStack = &ArKernelBootStack;
KernelFaultStack = &ArKernelFaultStack;
ProcessorBlock = &ArInitialProcessorBlock;
}
/* Initialize processor block */
ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
ArpInitializeGdt(ProcessorBlock);
ArpInitializeIdt(ProcessorBlock);
ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit);
ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit);
ArLoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
ArpInitializeSegments();
/* Initialize processor registers */
ArpInitializeProcessorRegisters();
/* Identify processor */
ArpIdentifyProcessor();
}
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
return (PVOID)BootStack;
}
/**
@@ -123,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/
XTAPI
VOID
ArpIdentifyProcessor(VOID)
ProcSup::IdentifyProcessor(VOID)
{
PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters;
@@ -141,7 +53,7 @@ ArpIdentifyProcessor(VOID)
ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx;
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -190,6 +102,77 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */
}
/**
* Initializes i686 processor specific structures.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
{
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack;
PKPROCESSOR_BLOCK ProcessorBlock;
PKGDTENTRY Gdt;
PKIDTENTRY Idt;
PKTSS Tss;
/* Check if processor structures buffer provided */
if(ProcessorStructures)
{
/* Assign CPU structures from provided buffer */
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
&KernelBootStack, &KernelFaultStack);
/* Use global IDT */
Idt = InitialIdt;
}
else
{
/* Use initial structures */
Gdt = InitialGdt;
Idt = InitialIdt;
Tss = &InitialTss;
KernelBootStack = &BootStack;
KernelFaultStack = &FaultStack;
ProcessorBlock = &InitialProcessorBlock;
}
/* Initialize processor block */
InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack);
/* Initialize GDT, IDT and TSS */
InitializeGdt(ProcessorBlock);
InitializeIdt(ProcessorBlock);
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
/* Set GDT and IDT descriptors */
GdtDescriptor.Base = Gdt;
GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1;
IdtDescriptor.Base = Idt;
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */
CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Enter passive IRQ level */
HlSetRunLevel(PASSIVE_LEVEL);
/* Initialize segment registers */
InitializeSegments();
/* Initialize processor registers */
InitializeProcessorRegisters();
/* Identify processor */
IdentifyProcessor();
}
/**
* Initializes the kernel's Global Descriptor Table (GDT).
*
@@ -202,23 +185,23 @@ ArpIdentifyProcessor(VOID)
*/
XTAPI
VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
/* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0);
}
/**
@@ -233,7 +216,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/
XTAPI
VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{
UINT Vector;
@@ -241,34 +224,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
}
/* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2E, ArpTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
}
/**
@@ -292,18 +275,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/
XTAPI
VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack)
{
/* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock;
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = Gdt;
ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss;
@@ -320,10 +303,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL;
ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL;
@@ -338,13 +321,13 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/
XTAPI
VOID
ArpInitializeProcessorRegisters(VOID)
ProcSup::InitializeProcessorRegisters(VOID)
{
/* Clear EFLAGS register */
ArWriteEflagsRegister(0);
CpuFunc::WriteEflagsRegister(0);
/* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP);
CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
}
/**
@@ -374,12 +357,12 @@ ArpInitializeProcessorRegisters(VOID)
*/
XTAPI
VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack)
{
UINT_PTR Address;
@@ -394,15 +377,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */
*Gdt = (PVOID)Address;
*Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt);
/* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address;
*ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock);
/* Assign a space for TSS */
*Tss = (PVOID)Address;
*Tss = (PKTSS)(PVOID)Address;
}
/**
@@ -414,13 +397,13 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/
XTAPI
VOID
ArpInitializeSegments(VOID)
ProcSup::InitializeSegments(VOID)
{
/* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R0_PB);
CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
}
/**
@@ -435,9 +418,9 @@ ArpInitializeSegments(VOID)
*/
XTAPI
VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack)
{
/* Clear I/O map */
RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE);
@@ -468,8 +451,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
/* Initialize task gates for DoubleFault and NMI traps */
ArpSetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
ArpSetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
}
/**
@@ -484,8 +467,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/
XTAPI
VOID
ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
{
PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss;
@@ -498,20 +481,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
/* Initialize DoubleFault TSS and set initial state */
Tss = (PKTSS)ArpDoubleFaultTss;
Tss = (PKTSS)DoubleFaultTss;
Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3);
Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap08);
Tss->Eip = PtrToUlong(ArTrap0x08);
Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB;
Tss->Ss0 = KGDT_R0_DATA;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* Setup DoubleFault TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
@@ -555,13 +538,13 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/
XTAPI
VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode)
{
PKGDTENTRY GdtEntry;
UCHAR Granularity;
@@ -601,6 +584,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->Bits.Type = (Type & 0x1F);
}
/**
* Updates an existing i686 GDT entry with new base address.
*
* @param Gdt
* Supplies a pointer to the GDT.
*
* @param Selector
* Specifies a segment selector of the GDT entry.
*
* @param Base
* Specifies a base address value of the descriptor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base)
{
PKGDTENTRY GdtEntry;
/* Get GDT entry */
GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK));
/* Set new GDT descriptor base */
GdtEntry->BaseLow = (Base & 0xFFFF);
GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF);
GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF);
}
/**
* Fills in a call, interrupt, task or trap gate entry.
*
@@ -628,12 +644,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/
XTAPI
VOID
ArpSetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
{
/* Setup the gate */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
@@ -654,8 +670,8 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
*/
XTAPI
VOID
ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack)
{
PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss;
@@ -668,19 +684,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
/* Initialize NMI TSS and set initial state */
Tss = (PKTSS)ArpNonMaskableInterruptTss;
Tss = (PKTSS)NonMaskableInterruptTss;
Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap02);
Tss->Eip = PtrToUlong(ArTrap0x02);
Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB;
ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss);
/* Setup NMI TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
@@ -693,3 +709,24 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
TssEntry->Bits.Present = 1;
TssEntry->Bits.Type = I686_TSS;
}
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
PVOID
ArGetBootStack(VOID)
{
return AR::ProcSup::GetBootStack();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTCLINK
XTAPI
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{
AR::ProcSup::InitializeProcessor(ProcessorStructures);
}

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/traps.c
* FILE: xtoskrnl/ar/i686/traps.cc
* DESCRIPTION: I686 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
/**
* Dispatches the trap provided by common trap handler.
*
@@ -21,110 +25,110 @@
*/
XTCDECL
VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
/* Check vector and call appropriate handler */
switch(TrapFrame->Vector)
{
case 0x00:
/* Divide By Zero exception */
ArpHandleTrap00(TrapFrame);
HandleTrap00(TrapFrame);
break;
case 0x01:
/* Debug exception */
ArpHandleTrap01(TrapFrame);
HandleTrap01(TrapFrame);
break;
case 0x02:
/* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame);
HandleTrap02(TrapFrame);
break;
case 0x03:
/* INT3 instruction executed */
ArpHandleTrap03(TrapFrame);
HandleTrap03(TrapFrame);
break;
case 0x04:
/* Overflow exception */
ArpHandleTrap04(TrapFrame);
HandleTrap04(TrapFrame);
break;
case 0x05:
/* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame);
HandleTrap05(TrapFrame);
break;
case 0x06:
/* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame);
HandleTrap06(TrapFrame);
break;
case 0x07:
/* Device Not Available exception */
ArpHandleTrap07(TrapFrame);
HandleTrap07(TrapFrame);
break;
case 0x08:
/* Double Fault exception */
ArpHandleTrap08(TrapFrame);
HandleTrap08(TrapFrame);
break;
case 0x09:
/* Segment Overrun exception */
ArpHandleTrap09(TrapFrame);
HandleTrap09(TrapFrame);
break;
case 0x0A:
/* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame);
HandleTrap0A(TrapFrame);
break;
case 0x0B:
/* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame);
HandleTrap0B(TrapFrame);
break;
case 0x0C:
/* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame);
HandleTrap0C(TrapFrame);
break;
case 0x0D:
/* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame);
HandleTrap0D(TrapFrame);
break;
case 0x0E:
/* Page Fault exception */
ArpHandleTrap0E(TrapFrame);
HandleTrap0E(TrapFrame);
break;
case 0x10:
/* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame);
HandleTrap10(TrapFrame);
break;
case 0x11:
/* Alignment Check exception */
ArpHandleTrap11(TrapFrame);
HandleTrap11(TrapFrame);
break;
case 0x12:
/* Machine Check exception */
ArpHandleTrap12(TrapFrame);
HandleTrap12(TrapFrame);
break;
case 0x13:
/* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame);
HandleTrap13(TrapFrame);
break;
case 0x2A:
/* Tick Count service request */
ArpHandleTrap2A(TrapFrame);
HandleTrap2A(TrapFrame);
break;
case 0x2B:
/* User-mode callback return */
ArpHandleTrap2B(TrapFrame);
HandleTrap2B(TrapFrame);
break;
case 0x2C:
/* Assertion raised */
ArpHandleTrap2C(TrapFrame);
HandleTrap2C(TrapFrame);
break;
case 0x2D:
/* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame);
HandleTrap2D(TrapFrame);
break;
case 0x2E:
/* System call service request */
ArpHandleTrap2E(TrapFrame);
HandleTrap2E(TrapFrame);
break;
default:
/* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame);
HandleTrapFF(TrapFrame);
break;
}
}
@@ -141,7 +145,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;);
@@ -159,7 +163,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;);
@@ -177,7 +181,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;);
@@ -195,7 +199,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;);
@@ -213,7 +217,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;);
@@ -231,7 +235,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;);
@@ -249,7 +253,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;);
@@ -267,7 +271,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;);
@@ -285,7 +289,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;);
@@ -303,7 +307,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;);
@@ -321,7 +325,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;);
@@ -339,7 +343,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;);
@@ -357,7 +361,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;);
@@ -375,7 +379,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;);
@@ -393,7 +397,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;);
@@ -411,7 +415,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;);
@@ -429,7 +433,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;);
@@ -447,7 +451,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;);
@@ -465,7 +469,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;);
@@ -483,7 +487,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n");
}
@@ -500,7 +504,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled Callback return service request (0x2B)!\n");
}
@@ -517,7 +521,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;);
@@ -535,7 +539,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;);
@@ -553,7 +557,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Unhandled system call (0x2E)!\n");
}
@@ -570,8 +574,28 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame)
*/
XTCDECL
VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame)
Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;);
}
} /* namespace */
/**
* C-linkage wrapper for dispatching the trap provided by common trap handler.
*
* @param TrapFrame
* Supplies a kernel trap frame pushed by common trap handler on the stack.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTCDECL
VOID
ArDispatchTrap(IN PKTRAP_FRAME TrapFrame)
{
AR::Traps::DispatchTrap(TrapFrame);
}

112
xtoskrnl/ex/exports.cc Normal file
View File

@@ -0,0 +1,112 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Acquires the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
*
* @since NT 5.1
*/
XTFASTCALL
BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
return EX::Rundown::AcquireProtection(Descriptor);
}
/**
* Marks the rundown descriptor as completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be completed.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::CompleteProtection(Descriptor);
}
/**
* Initializes the rundown protection descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::InitializeProtection(Descriptor);
}
/**
* Reinitializes the rundown protection structure after it has been completed.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be reinitialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReInitializeProtection(Descriptor);
}
/**
* Releases the rundown protection for given descriptor.
*
* @param Descriptor
* Supplies a pointer to the descriptor to be initialized.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::ReleaseProtection(Descriptor);
}
/**
* Waits until rundown protection calls are completed.
*
* @param Descriptor
* Supplies a pointer to the rundown block descriptor.
*
* @return This routine does not return any value.
*
* @since NT 5.1
*/
XTFASTCALL
VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
EX::Rundown::WaitForProtectionRelease(Descriptor);
}

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/rundown.c
* FILE: xtoskrnl/ex/rundown.cc
* DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
#include <xtos.hh>
/* Kernel Executive */
namespace EX
{
/**
* Acquires the rundown protection for given descriptor.
*
@@ -21,7 +25,7 @@
*/
XTFASTCALL
BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
ULONG_PTR CurrentValue, NewValue;
@@ -69,7 +73,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/
XTFASTCALL
VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
}
@@ -86,7 +90,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/
XTFASTCALL
VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
/* Reset descriptor counter */
Descriptor->Count = 0;
@@ -104,7 +108,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/
XTFASTCALL
VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
RtlAtomicExchangePointer(&Descriptor->Ptr, NULL);
}
@@ -121,7 +125,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/
XTFASTCALL
VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
ULONG_PTR CurrentValue, NewValue;
PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
@@ -136,7 +140,7 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count))
{
KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE);
KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE);
}
break;
@@ -172,7 +176,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/
XTFASTCALL
VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{
UNIMPLEMENTED;
}
} /* namespace */

View File

@@ -25,6 +25,10 @@ XTCDECL
VOID
ArFlushTlb(VOID);
XTAPI
PVOID
ArGetBootStack(VOID);
XTCDECL
ULONG
ArGetCpuFlags(VOID);
@@ -431,4 +435,8 @@ XTCDECL
VOID
ArpTrap0xE1(VOID);
XTCDECL
VOID
ArpTrap0xFF(VOID);
#endif /* __XTOSKRNL_AMD64_ARI_H */

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI
VOID
KepSwitchBootStack(IN ULONG_PTR Stack);
KepSwitchBootStack();
#endif /* __XTOSKRNL_AMD64_KEI_H */

18
xtoskrnl/includes/ar.hh Normal file
View File

@@ -0,0 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar.hh
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_HH
#define __XTOSKRNL_AR_HH
#include <xtos.hh>
#include XTOS_ARCH_HEADER(ar, cpufunc.hh)
#include XTOS_ARCH_HEADER(ar, procsup.hh)
#include XTOS_ARCH_HEADER(ar, traps.hh)
#endif /* __XTOSKRNL_AR_HH */

View File

@@ -0,0 +1,62 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/cpufunc.hh
* DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_CPUFUNC_HH
#define __XTOSKRNL_AR_CPUFUNC_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class CpuFunc
{
public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
STATIC XTCDECL VOID FlushTlb(VOID);
STATIC XTCDECL ULONG GetCpuFlags(VOID);
STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);
STATIC XTCDECL VOID Halt(VOID);
STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);
STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);
STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);
STATIC XTCDECL VOID LoadMxcsrRegister(IN ULONG Source);
STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,
IN ULONG Source);
STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);
STATIC XTCDECL VOID MemoryBarrier(VOID);
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);
STATIC XTCDECL ULONGLONG ReadGSQuadWord(ULONG Offset);
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
STATIC XTCDECL VOID SetInterruptFlag(VOID);
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,
OUT PVOID Destination);
STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);
STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value);
STATIC XTCDECL VOID YieldProcessor(VOID);
};
}
#endif /* __XTOSKRNL_AR_CPUFUNC_HH */

View File

@@ -0,0 +1,71 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/procsup.hh
* DESCRIPTION: Architecture-specific routines for AMD64 processor initialization and system structure setup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_PROCSUP_HH
#define __XTOSKRNL_AR_PROCSUP_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class ProcSup
{
private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];
STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss;
public:
STATIC XTAPI PVOID GetBootStack(VOID);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack);
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack);
STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode);
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
};
}
#endif /* __XTOSKRNL_AR_PROCSUP_HH */

View File

@@ -0,0 +1,180 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/amd64/traps.hh
* DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_TRAPS_HH
#define __XTOSKRNL_AR_TRAPS_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class Traps
{
public:
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
private:
STATIC XTCDECL VOID HandleSystemCall32(VOID);
STATIC XTCDECL VOID HandleSystemCall64(VOID);
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap1F(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2F(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapE1(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);
};
}
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x1F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xE1(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_TRAPS_HH */

View File

@@ -0,0 +1,61 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/cpufunc.hh
* DESCRIPTION: Architecture-specific CPU control and utility functions for low-level system operations
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_CPUFUNC_HH
#define __XTOSKRNL_AR_CPUFUNC_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class CpuFunc
{
public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
STATIC XTCDECL VOID FlushTlb(VOID);
STATIC XTCDECL ULONG GetCpuFlags(VOID);
STATIC XTASSEMBLY XTCDECL ULONG_PTR GetStackPointer(VOID);
STATIC XTCDECL VOID Halt(VOID);
STATIC XTCDECL BOOLEAN InterruptsEnabled(VOID);
STATIC XTCDECL VOID InvalidateTlbEntry(IN PVOID Address);
STATIC XTCDECL VOID LoadGlobalDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadInterruptDescriptorTable(IN PVOID Source);
STATIC XTCDECL VOID LoadLocalDescriptorTable(IN USHORT Source);
STATIC XTCDECL VOID LoadSegment(IN USHORT Segment,
IN ULONG Source);
STATIC XTCDECL VOID LoadTaskRegister(USHORT Source);
STATIC XTCDECL VOID MemoryBarrier(VOID);
STATIC XTCDECL ULONG_PTR ReadControlRegister(IN USHORT ControlRegister);
STATIC XTCDECL ULONG_PTR ReadDebugRegister(IN USHORT DebugRegister);
STATIC XTCDECL ULONG ReadFSDualWord(ULONG Offset);
STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register);
STATIC XTCDECL UINT ReadMxCsrRegister(VOID);
STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID);
STATIC XTCDECL VOID ReadWriteBarrier(VOID);
STATIC XTCDECL VOID SetInterruptFlag(VOID);
STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreInterruptDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreLocalDescriptorTable(OUT PVOID Destination);
STATIC XTCDECL VOID StoreSegment(IN USHORT Segment,
OUT PVOID Destination);
STATIC XTCDECL VOID StoreTaskRegister(OUT PVOID Destination);
STATIC XTCDECL VOID WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value);
STATIC XTCDECL VOID WriteEflagsRegister(IN UINT_PTR Value);
STATIC XTCDECL VOID WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value);
STATIC XTCDECL VOID YieldProcessor(VOID);
};
}
#endif /* __XTOSKRNL_AR_CPUFUNC_HH */

View File

@@ -0,0 +1,79 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/procsup.hh
* DESCRIPTION: Architecture-specific routines for i686 processor initialization and system structure setup
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_PROCSUP_HH
#define __XTOSKRNL_AR_PROCSUP_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class ProcSup
{
private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
STATIC UCHAR DoubleFaultTss[KTSS_IO_MAPS];
STATIC UCHAR FaultStack[KERNEL_STACK_SIZE];
STATIC KGDTENTRY InitialGdt[GDT_ENTRIES];
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
STATIC KTSS InitialTss;
STATIC UCHAR NonMaskableInterruptTss[KTSS_IO_MAPS];
public:
STATIC XTAPI PVOID GetBootStack(VOID);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
STATIC XTAPI VOID InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
STATIC XTAPI VOID InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack);
STATIC XTAPI VOID InitializeProcessorRegisters(VOID);
STATIC XTAPI VOID InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack);
STATIC XTAPI VOID InitializeSegments(VOID);
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base,
IN ULONG Limit,
IN UCHAR Type,
IN UCHAR Dpl,
IN UCHAR SegmentMode);
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);
};
}
#endif /* __XTOSKRNL_AR_PROCSUP_HH */

View File

@@ -0,0 +1,177 @@
/**@s
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ar/i686/traps.hh
* DESCRIPTION: Trap handling routines and the dispatcher for processor exceptions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_AR_TRAPS_HH
#define __XTOSKRNL_AR_TRAPS_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace AR
{
class Traps
{
public:
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame);
private:
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap01(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap02(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap03(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap04(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap05(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap06(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap07(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap08(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap09(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap0E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap10(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap11(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap12(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap13(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2A(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2B(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2C(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2D(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrap2E(IN PKTRAP_FRAME TrapFrame);
STATIC XTCDECL VOID HandleTrapFF(IN PKTRAP_FRAME TrapFrame);
};
}
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_TRAPS_HH */

16
xtoskrnl/includes/ex.hh Normal file
View File

@@ -0,0 +1,16 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ex.hh
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_EX_HH
#define __XTOSKRNL_EX_HH
#include <xtos.hh>
#include <ex/rundown.hh>
#endif /* __XTOSKRNL_EX_HH */

View File

@@ -0,0 +1,30 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ex/rundown.hh
* DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_EX_RUNDOWN_HH
#define __XTOSKRNL_EX_RUNDOWN_HH
#include <xtos.hh>
/* Architecture-specific Library */
namespace EX
{
class Rundown
{
public:
STATIC XTFASTCALL BOOLEAN AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor);
STATIC XTFASTCALL VOID WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor);
};
}
#endif /* __XTOSKRNL_EX_RUNDOWN_HH */

View File

@@ -25,6 +25,10 @@ XTCDECL
VOID
ArFlushTlb(VOID);
XTAPI
PVOID
ArGetBootStack(VOID);
XTCDECL
ULONG
ArGetCpuFlags(VOID);

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI
VOID
KepSwitchBootStack(IN ULONG_PTR Stack);
KepSwitchBootStack();
#endif /* __XTOSKRNL_I686_KEI_H */

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

@@ -0,0 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke.hh
* DESCRIPTION: Kernel Library
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_HH
#define __XTOSKRNL_KE_HH
#include <xtos.hh>
#include <ke/apc.hh>
#include <ke/bootinfo.hh>
#include <ke/crash.hh>
#include <ke/dpc.hh>
#include <ke/event.hh>
#include <ke/irq.hh>
#include <ke/kprocess.hh>
#include <ke/krnlinit.hh>
#include <ke/kthread.hh>
#include <ke/kubsan.hh>
#include <ke/proc.hh>
#include <ke/runlevel.hh>
#include <ke/semphore.hh>
#include <ke/spinlock.hh>
#include <ke/sysres.hh>
#include <ke/timer.hh>
#endif /* __XTOSKRNL_KE_HH */

View File

@@ -0,0 +1,32 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/apc.hh
* DESCRIPTION: Kernel APC objects support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_APC_HH
#define __XTOSKRNL_KE_APC_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Apc
{
public:
STATIC XTAPI VOID InitializeApc(IN PKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine,
IN PKNORMAL_ROUTINE NormalRoutine,
IN KPROCESSOR_MODE ApcMode,
IN PVOID Context);
};
}
#endif /* __XTOSKRNL_KE_APC_HH */

View File

@@ -0,0 +1,38 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/bootinfo.hh
* DESCRIPTION: Bootloader-provided system information handling support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_BOOTINFO_HH
#define __XTOSKRNL_KE_BOOTINFO_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class BootInformation
{
private:
STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
public:
STATIC XTAPI PVOID GetDebugPrint(VOID);
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
OUT PCWSTR *Parameter);
STATIC XTAPI PLIST_ENTRY GetSystemResources(VOID);
STATIC XTAPI VOID SetInitializationBlock(IN PKERNEL_INITIALIZATION_BLOCK Block);
STATIC XTAPI PKERNEL_INITIALIZATION_BLOCK GetInitializationBlock(VOID)
{
return InitializationBlock;
}
};
}
#endif /* __XTOSKRNL_KE_BOOTINFO_HH */

View File

@@ -0,0 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/crash.hh
* DESCRIPTION: System shutdown and kernel panic mechanism
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_CRASH_HH
#define __XTOSKRNL_KE_CRASH_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Crash
{
public:
STATIC XTAPI VOID HaltSystem(VOID);
STATIC XTAPI VOID Panic(IN ULONG Code);
STATIC XTAPI VOID PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4);
};
}
#endif /* __XTOSKRNL_KE_CRASH_HH */

View File

@@ -0,0 +1,37 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/dpc.hh
* DESCRIPTION: Deferred Procedure Call (DPC) support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_DPC_HH
#define __XTOSKRNL_KE_DPC_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Dpc
{
public:
STATIC XTAPI VOID InitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext);
STATIC XTAPI VOID InitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext);
STATIC XTAPI VOID SetTargetProcessor(IN PKDPC Dpc,
IN CCHAR Number);
STATIC XTAPI VOID SignalCallDone(IN PVOID SystemArgument);
STATIC XTAPI BOOLEAN SignalCallSynchronize(IN PVOID SystemArgument);
private:
STATIC XTFASTCALL VOID RetireList(IN PKPROCESSOR_CONTROL_BLOCK Prcb);
};
}
#endif /* __XTOSKRNL_KE_DPC_HH */

View File

@@ -0,0 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/event.hh
* DESCRIPTION: Kernel events support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_EVENT_HH
#define __XTOSKRNL_KE_EVENT_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Event
{
public:
STATIC XTAPI VOID ClearEvent(IN PKEVENT Event);
STATIC XTAPI VOID InitializeEvent(OUT PKEVENT Event,
IN KEVENT_TYPE EventType,
IN BOOLEAN InitialState);
STATIC XTAPI LONG SetEvent(IN PKEVENT Event,
IN KPRIORITY Increment,
IN BOOLEAN Wait);
};
}
#endif /* __XTOSKRNL_KE_EVENT_HH */

View File

@@ -0,0 +1,27 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/info.hh
* DESCRIPTION: Generic kernel information support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_INFO_HH
#define __XTOSKRNL_KE_INFO_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Info
{
public:
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
OUT PCWSTR *Parameter);
};
}
#endif /* __XTOSKRNL_KE_INFO_HH */

View File

@@ -0,0 +1,26 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/irq.hh
* DESCRIPTION: Kernel interrupts support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_IRQ_HH
#define __XTOSKRNL_KE_IRQ_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Irq
{
public:
STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler);
};
}
#endif /* __XTOSKRNL_KE_IRQ_HH */

View File

@@ -0,0 +1,33 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/kprocess.hh
* DESCRIPTION: XT kernel process manipulation support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KPROCESS_HH
#define __XTOSKRNL_KE_KPROCESS_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class KProcess
{
private:
STATIC EPROCESS InitialProcess;
public:
STATIC XTAPI PEPROCESS GetInitialProcess(VOID);
STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process,
IN KPRIORITY Priority,
IN KAFFINITY Affinity,
IN PULONG_PTR DirectoryTable,
IN BOOLEAN Alignment);
};
}
#endif /* __XTOSKRNL_KE_KPROCESS_HH */

View File

@@ -0,0 +1,30 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/krnlinit.hh
* DESCRIPTION: XTOS Kernel initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KRNLINIT_HH
#define __XTOSKRNL_KE_KRNLINIT_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class KernelInit
{
public:
STATIC XTAPI VOID InitializeMachine(VOID);
STATIC XTAPI VOID SwitchBootStack(VOID);
private:
STATIC XTAPI VOID InitializeKernel(VOID);
STATIC XTAPI VOID StartKernel(VOID);
};
}
#endif /* __XTOSKRNL_KE_KRNLINIT_HH */

View File

@@ -0,0 +1,55 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/kthread.hh
* DESCRIPTION: XT kernel thread manipulation support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KTHREAD_HH
#define __XTOSKRNL_KE_KTHREAD_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class KThread
{
private:
STATIC ETHREAD InitialThread;
public:
STATIC XTFASTCALL VOID ExitDispatcher(IN KRUNLEVEL OldRunLevel);
STATIC XTAPI PETHREAD GetInitialThread(VOID);
STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process,
IN OUT PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext,
IN PCONTEXT Context,
IN PVOID EnvironmentBlock,
IN PVOID Stack,
IN BOOLEAN StartThread);
STATIC XTAPI VOID StartThread(IN PKTHREAD Thread);
private:
STATIC XTAPI VOID InitializeThreadContext(IN PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext,
IN PCONTEXT ContextRecord);
STATIC XTAPI VOID SuspendNop(IN PKAPC Apc,
IN OUT PKNORMAL_ROUTINE *NormalRoutine,
IN OUT PVOID *NormalContext,
IN OUT PVOID *SystemArgument1,
IN OUT PVOID *SystemArgument2);
STATIC XTAPI VOID SuspendRundown(IN PKAPC Apc);
STATIC XTAPI VOID SuspendThread(IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2);
};
}
#endif /* __XTOSKRNL_KE_KTHREAD_HH */

View File

@@ -0,0 +1,67 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/kubsan.hh
* DESCRIPTION: Kernel Undefined Behaviour Sanitizer (UBSAN) error reporting handler
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_KUBSAN_HH
#define __XTOSKRNL_KE_KUBSAN_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class KUbsan
{
private:
STATIC BOOLEAN ActiveFrame;
public:
STATIC XTCDECL VOID HandleDivisionOverflow(PKUBSAN_OVERFLOW_DATA Data,
PVOID Lhs,
PVOID Rhs);
STATIC XTCDECL VOID HandleFloatCastOverflow(PKUBSAN_FLOAT_CAST_OVERFLOW_DATA Data,
ULONG_PTR Lhs,
ULONG_PTR Rhs);
STATIC XTCDECL VOID HandleFunctionTypeMismatch(PKUBSAN_FUNCTION_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer);
STATIC XTCDECL VOID HandleIntegerOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR Lhs,
ULONG_PTR Rhs);
STATIC XTCDECL VOID HandleInvalidBuiltin(PKUBSAN_INVALID_BUILTIN_DATA Data);
STATIC XTCDECL VOID HandleMisalignedAccess(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer);
STATIC XTCDECL VOID HandleNegateOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR OldValue);
STATIC XTCDECL VOID HandleNullPointerDereference(PKUBSAN_TYPE_MISMATCH_DATA Data);
STATIC XTCDECL VOID HandleObjectSizeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer);
STATIC XTCDECL VOID HandleOutOfBounds(PKUBSAN_OUT_OF_BOUNDS_DATA Data,
ULONG_PTR Index);
STATIC XTCDECL VOID HandlePointerOverflow(PKUBSAN_OVERFLOW_DATA Data,
ULONG_PTR Lhs,
ULONG_PTR Rhs);
STATIC XTCDECL VOID HandleShiftOutOfBounds(PKUBSAN_SHIFT_OUT_OF_BOUNDS_DATA Data,
ULONG_PTR Lhs,
ULONG_PTR Rhs);
STATIC XTCDECL VOID HandleTypeMismatch(PKUBSAN_TYPE_MISMATCH_DATA Data,
ULONG_PTR Pointer);
private:
STATIC XTCDECL BOOLEAN CheckReport(PKUBSAN_SOURCE_LOCATION Location);
STATIC XTCDECL VOID EnterFrame(PKUBSAN_SOURCE_LOCATION Location,
PCCHAR Reason);
STATIC XTCDECL LONGLONG GetSignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
PVOID Value);
STATIC XTCDECL PCCHAR GetTypeKind(UCHAR TypeCheckKind);
STATIC XTCDECL ULONGLONG GetUnsignedValue(PKUBSAN_TYPE_DESCRIPTOR Type,
PVOID Value);
STATIC XTCDECL VOID LeaveFrame();
};
}
#endif /* __XTOSKRNL_KE_KUBSAN_HH */

View File

@@ -0,0 +1,29 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/proc.hh
* DESCRIPTION: Processor-related functionality for the kernel
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_PROC_HH
#define __XTOSKRNL_KE_PROC_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Processor
{
public:
STATIC XTAPI PKPROCESSOR_BLOCK GetCurrentProcessorBlock(VOID);
STATIC XTAPI PKPROCESSOR_CONTROL_BLOCK GetCurrentProcessorControlBlock(VOID);
STATIC XTAPI ULONG GetCurrentProcessorNumber(VOID);
STATIC XTAPI PKTHREAD GetCurrentThread(VOID);
STATIC XTAPI VOID SaveProcessorState(OUT PKPROCESSOR_STATE CpuState);
};
}
#endif /* __XTOSKRNL_KE_PROC_HH */

View File

@@ -0,0 +1,27 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/runlevel.hh
* DESCRIPTION: Running Level management support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_RUNLEVEL_HH
#define __XTOSKRNL_KE_RUNLEVEL_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class RunLevel
{
public:
STATIC XTFASTCALL KRUNLEVEL GetCurrentRunLevel(VOID);
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
};
}
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */

View File

@@ -0,0 +1,32 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/semphore.hh
* DESCRIPTION: Semaphores support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SEMPHORE_HH
#define __XTOSKRNL_KE_SEMPHORE_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Semaphore
{
public:
STATIC XTAPI VOID InitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count,
IN LONG Limit);
STATIC XTAPI LONG ReadState(IN PKSEMAPHORE Semaphore);
STATIC XTAPI LONG ReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN KPRIORITY Increment,
IN LONG Adjustment,
IN BOOLEAN Wait);
};
}
#endif /* __XTOSKRNL_KE_SEMPHORE_HH */

View File

@@ -0,0 +1,29 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/spinlock.hh
* DESCRIPTION: Spinlocks support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SPINLOCK_HH
#define __XTOSKRNL_KE_SPINLOCK_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class SpinLock
{
public:
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
};
}
#endif /* __XTOSKRNL_KE_SPINLOCK_HH */

View File

@@ -0,0 +1,40 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/sysres.hh
* DESCRIPTION: System boot resources management
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_SYSRES_HH
#define __XTOSKRNL_KE_SYSRES_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class SystemResources
{
private:
STATIC LIST_ENTRY ResourcesListHead;
STATIC KSPIN_LOCK ResourcesLock;
public:
STATIC XTAPI XTSTATUS AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
STATIC XTAPI XTSTATUS GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
STATIC XTAPI VOID InitializeResources(VOID);
STATIC XTAPI VOID ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader);
private:
STATIC XTAPI XTSTATUS GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
IN BOOLEAN ResourceLock,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader);
};
}
#endif /* __XTOSKRNL_KE_SYSRES_HH */

View File

@@ -0,0 +1,37 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/timer.hh
* DESCRIPTION: Kernel timer object support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_TIMER_HH
#define __XTOSKRNL_KE_TIMER_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Timer
{
public:
STATIC XTAPI BOOLEAN CancelTimer(IN PKTIMER Timer);
STATIC XTAPI VOID ClearTimer(IN PKTIMER Timer);
STATIC XTAPI BOOLEAN GetState(IN PKTIMER Timer);
STATIC XTAPI VOID InitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type);
STATIC XTAPI ULONGLONG QueryTimer(IN PKTIMER Timer);
STATIC XTAPI VOID SetTimer(IN PKTIMER Timer,
IN LARGE_INTEGER DueTime,
IN LONG Period,
IN PKDPC Dpc);
private:
STATIC XTAPI VOID RemoveTimer(IN OUT PKTIMER Timer);
};
}
#endif /* __XTOSKRNL_KE_TIMER_HH */

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

@@ -0,0 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/xtos.hh
* DESCRIPTION: Top level header for the XT kernel
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
/* Preprocessor macro for including arch-specific headers */
#define XTOS_ARCH_HEADER(subsystem, header) STRINGIFY(subsystem/_ARCH/header)
/* Temporary includes for C code compatibility */
extern "C" {
/* XT Development Kit */
#include <xtkmapi.h>
/* XT OS version */
#include <xtver.h>
/* Kernel specific headers */
#include <xtos.h>
}
#include <ar.hh>
#include <ex.hh>
#include <ke.hh>

View File

@@ -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);
}

View File

@@ -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, ArKernelBootStack, 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,29 +112,41 @@ 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 to a new kernel boot stack.
* Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.
*
* @return This routine does not return any value
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KepSwitchBootStack(IN ULONG_PTR Stack)
KernelInit::SwitchBootStack(VOID)
{
/* Discard old stack frame, switch stack and jump to KepStartKernel() */
ULONG_PTR Stack;
PVOID StartKernel;
/* 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 */

View File

@@ -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 */

View File

@@ -1,114 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/amd64/proc.c
* DESCRIPTION: AMD64 processor-related functionality for the kernel
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Gets the processor block for the currently executing processor.
*
* @return This routine returns the current processor block read from the GS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_BLOCK
KeGetCurrentProcessorBlock(VOID)
{
/* Get processor block from GS register */
return (PKPROCESSOR_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
}
/**
* Gets the processor control block for the currently executing processor.
*
* @return This routine returns the current processor control block read from the GS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_CONTROL_BLOCK
KeGetCurrentProcessorControlBlock(VOID)
{
return (PKPROCESSOR_CONTROL_BLOCK)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
}
/**
* Gets the number of the currently executing processor.
*
* @return This routine returns the zero-indexed processor number.
*
* @since XT 1.0
*/
XTAPI
ULONG
KeGetCurrentProcessorNumber(VOID)
{
return (ULONG)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
}
/**
* Gets the current thread running on the currently executing processor.
*
* @return This routine returns the address of the current thread object.
*
* @since NT 3.5
*/
XTAPI
PKTHREAD
KeGetCurrentThread(VOID)
{
return (PKTHREAD)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
}
/**
* Saves the current processor state.
*
* @param State
* Supplies a pointer to the processor state structure.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
/* Save CR registers */
CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4);
CpuState->SpecialRegisters.Cr8 = ArReadControlRegister(8);
/* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7);
/* Save MSR registers */
CpuState->SpecialRegisters.MsrGsBase = ArReadModelSpecificRegister(X86_MSR_GSBASE);
CpuState->SpecialRegisters.MsrGsSwap = ArReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);
CpuState->SpecialRegisters.MsrCStar = ArReadModelSpecificRegister(X86_MSR_CSTAR);
CpuState->SpecialRegisters.MsrLStar = ArReadModelSpecificRegister(X86_MSR_LSTAR);
CpuState->SpecialRegisters.MsrStar = ArReadModelSpecificRegister(X86_MSR_STAR);
CpuState->SpecialRegisters.MsrSyscallMask = ArReadModelSpecificRegister(X86_MSR_FMASK);
/* Save XMM control/status register */
CpuState->SpecialRegisters.MxCsr = ArReadMxCsrRegister();
/* Save GDT, IDT, LDT and TaskRegister */
ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr);
}

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

@@ -0,0 +1,162 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/amd64/proc.cc
* DESCRIPTION: AMD64 processor-related functionality for the kernel
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
/**
* Gets the processor block for the currently executing processor.
*
* @return This routine returns the current processor block read from the GS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_BLOCK
Processor::GetCurrentProcessorBlock(VOID)
{
/* Get processor block from GS register */
return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
}
/**
* Gets the processor control block for the currently executing processor.
*
* @return This routine returns the current processor control block read from the GS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_CONTROL_BLOCK
Processor::GetCurrentProcessorControlBlock(VOID)
{
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
}
/**
* Gets the number of the currently executing processor.
*
* @return This routine returns the zero-indexed processor number.
*
* @since XT 1.0
*/
XTAPI
ULONG
Processor::GetCurrentProcessorNumber(VOID)
{
return (ULONG)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
}
/**
* Gets the current thread running on the currently executing processor.
*
* @return This routine returns the address of the current thread object.
*
* @since NT 3.5
*/
XTAPI
PKTHREAD
Processor::GetCurrentThread(VOID)
{
return (PKTHREAD)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
}
/**
* Saves the current processor state.
*
* @param State
* Supplies a pointer to the processor state structure.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
/* Save CR registers */
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4);
CpuState->SpecialRegisters.Cr8 = AR::CpuFunc::ReadControlRegister(8);
/* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7);
/* Save MSR registers */
CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_GSBASE);
CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);
CpuState->SpecialRegisters.MsrCStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_CSTAR);
CpuState->SpecialRegisters.MsrLStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_LSTAR);
CpuState->SpecialRegisters.MsrStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_STAR);
CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_FMASK);
/* Save XMM control/status register */
CpuState->SpecialRegisters.MxCsr = AR::CpuFunc::ReadMxCsrRegister();
/* Save GDT, IDT, LDT and TaskRegister */
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
}
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKPROCESSOR_BLOCK
KeGetCurrentProcessorBlock(VOID)
{
return KE::Processor::GetCurrentProcessorBlock();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKPROCESSOR_CONTROL_BLOCK
KeGetCurrentProcessorControlBlock(VOID)
{
return KE::Processor::GetCurrentProcessorControlBlock();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
ULONG
KeGetCurrentProcessorNumber(VOID)
{
return KE::Processor::GetCurrentProcessorNumber();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKTHREAD
KeGetCurrentThread(VOID)
{
return KE::Processor::GetCurrentThread();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
VOID
KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
KE::Processor::SaveProcessorState(CpuState);
}

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* 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 */

View File

@@ -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();
}

View File

@@ -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
View File

@@ -0,0 +1,34 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/data.cc
* DESCRIPTION:
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
/* Kernel initialization block passed by boot loader */
PKERNEL_INITIALIZATION_BLOCK BootInformation::InitializationBlock = {};
/* Kernel boot resources list */
LIST_ENTRY SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK SystemResources::ResourcesLock;
/* Kernel initial process */
EPROCESS KProcess::InitialProcess;
/* Kernel initial thread */
ETHREAD KThread::InitialThread = {};
/* Kernel UBSAN active frame flag */
BOOLEAN KUbsan::ActiveFrame = FALSE;
} /* namespace */

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* 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 */

View File

@@ -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
View File

@@ -0,0 +1,482 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/exports.cc
* DESCRIPTION: C-compatible API wrappers for exported kernel functions
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
/**
* Acquires a specified queued spinlock.
*
* @param LockLevel
* Supplies the queued spinlock level.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTFASTCALL
VOID
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
KE::SpinLock::AcquireQueuedSpinLock(LockLevel);
}
/**
* Acquires a kernel spin lock.
*
* @param SpinLock
* Supplies a pointer to the kernel spin lock.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTFASTCALL
VOID
KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
{
KE::SpinLock::AcquireSpinLock(SpinLock);
}
/**
* Looks for an unacquired system resource of the specified type and acquires it.
*
* @param ResourceType
* Supplies system resource type.
*
* @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{
return KE::SystemResources::AcquireResource(ResourceType, ResourceHeader);
}
/**
* Cancels the timer.
*
* @param Timer
* Supplies a pointer to a timer object.
*
* @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
BOOLEAN
KeCancelTimer(IN PKTIMER Timer)
{
return KE::Timer::CancelTimer(Timer);
}
/**
* Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.
*
* @param ResourceType
* Supplies system resource type.
*
* @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
XTSTATUS
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{
return KE::SystemResources::GetResource(ResourceType, ResourceHeader);
}
/**
* Reads the current signal state of the given timer.
*
* @param Timer
* Supplies a pointer to a timer object.
*
* @return This routine returns TRUE if the timer is set, or FALSE otherwise.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
BOOLEAN
KeGetTimerState(IN PKTIMER Timer)
{
return KE::Timer::GetState(Timer);
}
/**
* Initializes an APC object.
*
* @param Apc
* Supplies a pointer to the APC object.
*
* @param Thread
* Supplies a pointer to the thread object.
*
* @param Environment
* Specifies an environment in which the APC will run.
*
* @param KernelRoutine
* Supplies a pointer to routine called at APC_LEVEL.
*
* @param RundownRoutine
* Supplies a pointer to routine called on thread exit.
*
* @param NormalRoutine
* Supplies a pointer to routine called at IRQL 0.
*
* @param ApcMode
* Specifies processor mode, in which NormalRoutine gets called.
*
* @param Context
* Supplies a pointer to memory area containing data passed to NormalRoutine.
*
* @return This routine does not return any value.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
VOID
KeInitializeApc(IN PKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine,
IN PKNORMAL_ROUTINE NormalRoutine,
IN KPROCESSOR_MODE ApcMode,
IN PVOID Context)
{
KE::Apc::InitializeApc(Apc, Thread, Environment, KernelRoutine, RundownRoutine, NormalRoutine, ApcMode, Context);
}
/**
* Initializes Deferred Procedure Call (DPC) object.
*
* @param Dpc
* Supplies a pointer to the DPC being initialized.
*
* @param DpcRoutine
* Supplies a pointer to the DPC routine being called on object removal.
*
* @param DpcContext
* Supplies a pointer to memory area containing context data for DPC routine.
*
* @return This routine does not return any value.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
VOID
KeInitializeDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext)
{
KE::Dpc::InitializeDpc(Dpc, DpcRoutine, DpcContext);
}
/**
* Initializes Deferred Procedure Call (DPC) object.
*
* @param Dpc
* Supplies a pointer to the DPC being initialized.
*
* @param DpcRoutine
* Supplies a pointer to the DPC routine being called on object removal.
*
* @param DpcContext
* Supplies a pointer to memory area containing context data for DPC routine.
*
* @return This routine does not return any value.
*
* @since NT 5.2
*/
XTCLINK
XTAPI
VOID
KeInitializeThreadedDpc(IN PKDPC Dpc,
IN PKDEFERRED_ROUTINE DpcRoutine,
IN PVOID DpcContext)
{
KE::Dpc::InitializeThreadedDpc(Dpc, DpcRoutine, DpcContext);
}
/**
* Initializes an extended kernel timer.
*
* @param Timer
* Supplies a pointer to a timer object.
*
* @param Type
* Supplies the type of the timer.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
VOID
KeInitializeTimer(OUT PKTIMER Timer,
IN KTIMER_TYPE Type)
{
KE::Timer::InitializeTimer(Timer, Type);
}
/**
* Initializes a kernel semaphore object.
*
* @param Semaphore
* Supplies a pointer to a semaphore object.
*
* @param Count
* Specifies the initial count value of the semaphore.
*
* @param Limit
* Specifies a maximum count value of the semaphore.
*
* @return This routine does not return any value.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
VOID
KeInitializeSemaphore(IN PKSEMAPHORE Semaphore,
IN LONG Count,
IN LONG Limit)
{
KE::Semaphore::InitializeSemaphore(Semaphore, Count, Limit);
}
/**
* Initializes a kernel spinlock object.
*
* @param SpinLock
* Supplies a pointer to a kernel spin lock.
*
* @return This routine does not return any value.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
VOID
KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
{
KE::SpinLock::InitializeSpinLock(SpinLock);
}
/**
* Reads semaphore's current signal state.
*
* @param Semaphore
* Supplies a pointer to a semaphore object.
*
* @return This routine returns the current signal state of the semaphore.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
LONG
KeReadSemaphoreState(IN PKSEMAPHORE Semaphore)
{
return KE::Semaphore::ReadState(Semaphore);
}
/**
* Releases a queued spinlock.
*
* @param LockLevel
* Supplies the queued spinlock level.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTFASTCALL
VOID
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
KE::SpinLock::ReleaseQueuedSpinLock(LockLevel);
}
/**
* Releases a semaphore.
*
* @param Semaphore
* Supplies a pointer to a semaphore object.
*
* @param Increment
* Specifies the priority increment value of the semaphore.
*
* @param Adjustment
* Specifies adjustment value added to the semaphore's initial count value.
*
* @param Wait
* Determines whether release of the semaphore will be followed by a kernel wait routine call or not.
*
* @return This routine returns a previous signal state of the semaphore.
*
* @since NT 3.5
*/
XTCLINK
XTAPI
LONG
KeReleaseSemaphore(IN PKSEMAPHORE Semaphore,
IN KPRIORITY Increment,
IN LONG Adjustment,
IN BOOLEAN Wait)
{
return KE::Semaphore::ReleaseSemaphore(Semaphore, Increment, Adjustment, Wait);
}
/**
* Releases a kernel spin lock.
*
* @param SpinLock
* Supplies a pointer to the kernel spin lock.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTFASTCALL
VOID
KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
{
KE::SpinLock::ReleaseSpinLock(SpinLock);
}
/**
* Releases system resource.
*
* @param ResourceHeader
* Specifies a pointer to the system resource header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
VOID
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
{
KE::SystemResources::ReleaseResource(ResourceHeader);
}
/**
* Sets the target processor number for DPC.
*
* @param Dpc
* Supplies a pointer to the DPC object.
*
* @param Number
* Supplies the target processor number.
*
* @return This routine does not return any value.
*
* @since NT 4.0
*/
XTCLINK
XTAPI
VOID
KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number)
{
KE::Dpc::SetTargetProcessor(Dpc, Number);
}
/**
* Sets the supplied timer to expire at the specified time.
*
* @param Timer
* Supplies a pointer to a timer object.
*
* @param DueTime
* Supplies the time at which the timer should expire (both absolute and relative times are supported).
*
* @param Period
* Supplies the timer period.
*
* @param Dpc
* Supplies a pointer to a Deferred Procedure Call (DPC) object.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCLINK
XTAPI
VOID
KeSetTimer(IN PKTIMER Timer,
IN LARGE_INTEGER DueTime,
IN LONG Period,
IN PKDPC Dpc)
{
KE::Timer::SetTimer(Timer, DueTime, Period, Dpc);
}
/**
* Decrements the DPC call barier.
*
* @param SystemArgument
* Supplies an address of the DPC call barrier.
*
* @return This routine does not return any value.
*
* @since NT 5.2
*/
XTCLINK
XTAPI
VOID
KeSignalCallDpcDone(IN PVOID SystemArgument)
{
KE::Dpc::SignalCallDone(SystemArgument);
}
/**
* Decrements the DPC call reverse barier.
*
* @param SystemArgument
* Supplies an address of the DPC call barrier.
*
* @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more.
*
* @since NT 5.2
*/
XTCLINK
XTAPI
BOOLEAN
KeSignalCallDpcSynchronize(IN PVOID SystemArgument)
{
return KE::Dpc::SignalCallSynchronize(SystemArgument);
}

View File

@@ -1,37 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/globals.c
* DESCRIPTION: Architecture independent global variables related to KE subsystem
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/* Pointer to boot loader provided DbgPrint() routine */
VOID (*KeDbgPrint)(IN PCWSTR Format, IN ...) = NULL;
/* Kernel initialization block passed by boot loader */
PKERNEL_INITIALIZATION_BLOCK KeInitializationBlock;
/* Kernel initial process */
EPROCESS KeInitialProcess;
/* Kernel initial thread */
ETHREAD KeInitialThread;
/* Kernel service descriptor table */
KSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable[KSERVICE_TABLES_COUNT];
/* Kernel process list */
LIST_ENTRY KepProcessListHead;
/* Kernel system resources list */
LIST_ENTRY KepSystemResourcesListHead;
/* Kernel system resources lock */
KSPIN_LOCK KepSystemResourcesLock;
/* Kernel UBSAN active frame flag */
BOOLEAN KepUbsanActiveFrame = FALSE;

View File

@@ -1,14 +1,18 @@
/**
* PROJECT: ExectOS
* 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);
}

View File

@@ -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, ArKernelBootStack, 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,31 +112,43 @@ 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 to a new kernel boot stack.
* Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine.
*
* @return This routine does not return any value
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KepSwitchBootStack(IN ULONG_PTR Stack)
KernelInit::SwitchBootStack(VOID)
{
/* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */
ULONG_PTR Stack;
PVOID StartKernel;
/* 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 */

View File

@@ -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 */

View File

@@ -1,102 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/i686/proc.c
* DESCRIPTION: I686 processor-related functionality for the kernel
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Gets the processor block for the currently executing processor.
*
* @return This routine returns the current processor block read from the FS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_BLOCK
KeGetCurrentProcessorBlock(VOID)
{
/* Get processor block from FS register */
return (PKPROCESSOR_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
}
/**
* Gets the processor control block for the currently executing processor.
*
* @return This routine returns the current processor control block read from the FS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_CONTROL_BLOCK
KeGetCurrentProcessorControlBlock(VOID)
{
return (PKPROCESSOR_CONTROL_BLOCK)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
}
/**
* Gets the number of the currently executing processor.
*
* @return This routine returns the zero-indexed processor number.
*
* @since XT 1.0
*/
XTAPI
ULONG
KeGetCurrentProcessorNumber(VOID)
{
return (ULONG)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
}
/**
* Gets the current thread running on the currently executing processor.
*
* @return This routine returns the address of the current thread object.
*
* @since NT 3.5
*/
XTAPI
PKTHREAD
KeGetCurrentThread(VOID)
{
return (PKTHREAD)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
}
/**
* Saves the current processor state.
*
* @param State
* Supplies a pointer to the processor state structure.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
/* Save CR registers */
CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4);
/* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7);
/* Save GDT, IDT, LDT and TaskRegister */
ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr);
}

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

@@ -0,0 +1,150 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/i686/proc.c
* DESCRIPTION: I686 processor-related functionality for the kernel
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
/**
* Gets the processor block for the currently executing processor.
*
* @return This routine returns the current processor block read from the FS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_BLOCK
Processor::GetCurrentProcessorBlock(VOID)
{
/* Get processor block from FS register */
return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
}
/**
* Gets the processor control block for the currently executing processor.
*
* @return This routine returns the current processor control block read from the FS register.
*
* @since XT 1.0
*/
XTAPI
PKPROCESSOR_CONTROL_BLOCK
Processor::GetCurrentProcessorControlBlock(VOID)
{
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
}
/**
* Gets the number of the currently executing processor.
*
* @return This routine returns the zero-indexed processor number.
*
* @since XT 1.0
*/
XTAPI
ULONG
Processor::GetCurrentProcessorNumber(VOID)
{
return (ULONG)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
}
/**
* Gets the current thread running on the currently executing processor.
*
* @return This routine returns the address of the current thread object.
*
* @since NT 3.5
*/
XTAPI
PKTHREAD
Processor::GetCurrentThread(VOID)
{
return (PKTHREAD)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
}
/**
* Saves the current processor state.
*
* @param State
* Supplies a pointer to the processor state structure.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
/* Save CR registers */
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4);
/* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7);
/* Save GDT, IDT, LDT and TaskRegister */
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
}
} /* namespace */
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKPROCESSOR_BLOCK
KeGetCurrentProcessorBlock(VOID)
{
return KE::Processor::GetCurrentProcessorBlock();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKPROCESSOR_CONTROL_BLOCK
KeGetCurrentProcessorControlBlock(VOID)
{
return KE::Processor::GetCurrentProcessorControlBlock();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
ULONG
KeGetCurrentProcessorNumber(VOID)
{
return KE::Processor::GetCurrentProcessorNumber();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
PKTHREAD
KeGetCurrentThread(VOID)
{
return KE::Processor::GetCurrentThread();
}
/* TEMPORARY FOR COMPATIBILITY WITH C CODE */
XTAPI
VOID
KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{
KE::Processor::SaveProcessorState(CpuState);
}

View File

@@ -1,14 +1,25 @@
/**
* PROJECT: ExectOS
* 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);
}

View File

@@ -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, setting the pointer to the top of the buffer and aligning it as required by the ABI */
KepSwitchBootStack(((ULONG_PTR)&ArKernelBootStack + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1));
/* Switch the boot stack and transfer control to the KepStartKernel() routine */
KernelInit::SwitchBootStack();
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

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

View File

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