Compare commits

9 Commits

Author SHA1 Message Date
510dccc5dc Add missing forward reference to KeGetInitializationBlock
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 36s
Builds / ExectOS (amd64, release) (push) Successful in 33s
Builds / ExectOS (i686, debug) (push) Successful in 30s
Builds / ExectOS (i686, release) (push) Successful in 29s
2025-09-10 15:38:30 +02:00
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
92 changed files with 4377 additions and 1403 deletions

View File

@@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23) set(CMAKE_C_STANDARD 23)
set(CMAKE_CXX_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_C_STANDARD_LIBRARIES "" CACHE INTERNAL "")
set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "")
# Clean linker flags # Clean linker flags
set(CMAKE_STATIC_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 */ /* Routines used by XTLDR */
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID); ArClearInterruptFlag(VOID);
XTCLINK
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers); ArCpuId(IN OUT PCPUID_REGISTERS Registers);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap); ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID); ArHalt(VOID);
XTCLINK
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister); ArReadControlRegister(IN USHORT ControlRegister);
XTCLINK
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register); ArReadModelSpecificRegister(IN ULONG Register);
XTCLINK
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, ArWriteControlRegister(IN USHORT ControlRegister,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -7,6 +7,7 @@
*/ */
/* Base XT headers */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.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 */ /* Base XT headers */
#include <xtcompat.h>
#include <xtdefs.h> #include <xtdefs.h>
#include <xtstatus.h> #include <xtstatus.h>
#include <xttarget.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 _MODE MODE, *PMODE;
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;
typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE;
/* Structures forward references */ /* Structures forward references */

View File

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

View File

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

View File

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

View File

@@ -1,15 +1,19 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/amd64/cpufunc.c * FILE: xtoskrnl/ar/amd64/cpufunc.cc
* DESCRIPTION: Routines to provide access to special AMD64 CPU instructions * DESCRIPTION: Routines to provide access to special AMD64 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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. * Instructs the processor to clear the interrupt flag.
* *
* @return This routine does not return any value. * @return This routine does not return any value.
@@ -18,7 +22,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID) CpuFunc::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers) CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,10 +80,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
ArFlushTlb(VOID) CpuFunc::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3)); WriteControlRegister(3, ReadControlRegister(3));
} }
/** /**
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID) CpuFunc::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArGetStackPointer(VOID) CpuFunc::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("movq %%rsp, %%rax\n" __asm__ volatile("movq %%rsp, %%rax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID) CpuFunc::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArInterruptsEnabled(VOID) CpuFunc::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
/* Get RFLAGS register */ /* Get RFLAGS register */
Flags = ArGetCpuFlags(); Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */ /* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArInvalidateTlbEntry(IN PVOID Address) CpuFunc::InvalidateTlbEntry(IN PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(IN PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadGlobalDescriptorTable(IN PVOID Source) CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadInterruptDescriptorTable(IN PVOID Source) CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadLocalDescriptorTable(IN USHORT Source) CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -251,7 +255,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadMxcsrRegister(IN ULONG Source) CpuFunc::LoadMxcsrRegister(IN ULONG Source)
{ {
__asm__ volatile("ldmxcsr %0" __asm__ volatile("ldmxcsr %0"
: :
@@ -273,7 +277,7 @@ ArLoadMxcsrRegister(IN ULONG Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadSegment(IN USHORT Segment, CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
@@ -335,7 +339,7 @@ ArLoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadTaskRegister(USHORT Source) CpuFunc::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -351,7 +355,7 @@ ArLoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArMemoryBarrier(VOID) CpuFunc::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("lock; orl $0, %0;" __asm__ volatile("lock; orl $0, %0;"
@@ -371,7 +375,7 @@ ArMemoryBarrier(VOID)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister) CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -435,7 +439,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister) CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -504,7 +508,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadGSQuadWord(ULONG Offset) CpuFunc::ReadGSQuadWord(ULONG Offset)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -527,7 +531,7 @@ ArReadGSQuadWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register) CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONG Low, High; ULONG Low, High;
@@ -548,7 +552,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
ArReadMxCsrRegister(VOID) CpuFunc::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -562,7 +566,7 @@ ArReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadTimeStampCounter(VOID) CpuFunc::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Low, High; ULONGLONG Low, High;
@@ -582,7 +586,7 @@ ArReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArReadWriteBarrier(VOID) CpuFunc::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -599,7 +603,7 @@ ArReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArSetInterruptFlag(VOID) CpuFunc::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -616,7 +620,7 @@ ArSetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -636,7 +640,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination) CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -656,7 +660,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -679,7 +683,7 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreSegment(IN USHORT Segment, CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
@@ -726,7 +730,7 @@ ArStoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreTaskRegister(OUT PVOID Destination) CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -749,7 +753,7 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
@@ -808,7 +812,7 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteDebugRegister(IN USHORT DebugRegister, CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
@@ -820,48 +824,56 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 1: case 1:
/* Write value to DR1 */ /* Write value to DR1 */
__asm__ volatile("mov %0, %%dr1" __asm__ volatile("mov %0, %%dr1"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 2: case 2:
/* Write value to DR2 */ /* Write value to DR2 */
__asm__ volatile("mov %0, %%dr2" __asm__ volatile("mov %0, %%dr2"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 3: case 3:
/* Write value to DR3 */ /* Write value to DR3 */
__asm__ volatile("mov %0, %%dr3" __asm__ volatile("mov %0, %%dr3"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 4: case 4:
/* Write value to DR4 */ /* Write value to DR4 */
__asm__ volatile("mov %0, %%dr4" __asm__ volatile("mov %0, %%dr4"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 5: case 5:
/* Write value to DR5 */ /* Write value to DR5 */
__asm__ volatile("mov %0, %%dr5" __asm__ volatile("mov %0, %%dr5"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 6: case 6:
/* Write value to DR6 */ /* Write value to DR6 */
__asm__ volatile("mov %0, %%dr6" __asm__ volatile("mov %0, %%dr6"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
case 7: case 7:
/* Write value to DR7 */ /* Write value to DR7 */
__asm__ volatile("mov %0, %%dr7" __asm__ volatile("mov %0, %%dr7"
: :
: "r" (Value) : "r" (Value)
: "memory"); : "memory");
break;
} }
} }
@@ -877,7 +889,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteEflagsRegister(IN UINT_PTR Value) CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -900,7 +912,7 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteModelSpecificRegister(IN ULONG Register, CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
ULONG Low = Value & 0xFFFFFFFF; ULONG Low = Value & 0xFFFFFFFF;
@@ -922,10 +934,187 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
ArYieldProcessor(VOID) CpuFunc::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :
: :
: "memory"); : "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 * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: AMD64 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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 * @since XT 1.0
*/ */
XTAPI PVOID ProcSup::GetBootStack(VOID)
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; return (PVOID)BootStack;
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);
} }
/** /**
@@ -128,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpIdentifyProcessor(VOID) ProcSup::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -143,10 +50,10 @@ ArpIdentifyProcessor(VOID)
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* 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[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -155,7 +62,7 @@ ArpIdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
ArCpuId(&CpuRegisters); CpuFunc::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -195,6 +102,81 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */ /* 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). * Initializes the kernel's Global Descriptor Table (GDT).
* *
@@ -207,19 +189,21 @@ ArpIdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase,
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0);
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2);
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_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 XTAPI
VOID VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -242,34 +226,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* 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 */ /* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, 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, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
} }
/** /**
@@ -293,7 +277,7 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
@@ -304,7 +288,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */ /* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = (PVOID)Gdt; ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt; ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss; ProcessorBlock->TssBase = Tss;
ProcessorBlock->Prcb.RspBase = Tss->Rsp0; ProcessorBlock->Prcb.RspBase = Tss->Rsp0;
@@ -322,10 +306,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */ /* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial MXCSR register value */ /* Set initial MXCSR register value */
ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR; ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR;
@@ -343,56 +327,50 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorRegisters(VOID) ProcSup::InitializeProcessorRegisters(VOID)
{ {
ULONGLONG PatAttributes; ULONGLONG PatAttributes;
/* Enable FXSAVE restore */ /* Enable FXSAVE restore */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR);
/* Enable XMMI exceptions */ /* Enable XMMI exceptions */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
/* Set debugger extension */ /* Set debugger extension */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE);
/* Enable large pages */ /* Enable large pages */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE); CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE);
/* Enable write-protection */ /* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
/* Set alignment mask */ /* Set alignment mask */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM);
/* Disable FPU monitoring */ /* Disable FPU monitoring */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP);
/* Disable x87 FPU exceptions */ /* Disable x87 FPU exceptions */
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE);
/* Flush the TLB */ /* Flush the TLB */
ArFlushTlb(); CpuFunc::FlushTlb();
/* Initialize system calls MSR */ /* Initialize system call MSRs */
ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); Traps::InitializeSystemCallMsrs();
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);
/* Enable No-Execute (NXE) in EFER MSR */ /* 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 */ /* Initialize Page Attribute Table */
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | 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); (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 */ /* Initialize MXCSR register */
ArLoadMxcsrRegister(INITIAL_MXCSR); CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
} }
/** /**
@@ -422,7 +400,7 @@ ArpInitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
@@ -442,15 +420,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
*Gdt = (PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt); Address += sizeof(InitialGdt);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock); Address += sizeof(InitialProcessorBlock);
/* Assign a space for TSS */ /* Assign a space for TSS */
*Tss = (PVOID)Address; *Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -462,15 +440,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeSegments(VOID) ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA); CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -488,7 +466,7 @@ ArpInitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
@@ -532,7 +510,7 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt, ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
@@ -580,6 +558,40 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->MustBeZero = 0; 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. * Fills in a call, interrupt, task or trap gate entry.
* *
@@ -607,7 +619,7 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetIdtGate(IN PKIDTENTRY Idt, ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
@@ -624,3 +636,24 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
Idt[Vector].Selector = Selector; Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE; 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 * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: AMD64 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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. * Dispatches the trap provided by common trap handler.
* *
@@ -21,124 +25,138 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x1F: case 0x1F:
/* Software Interrupt at APC level */ /* Software Interrupt at APC level */
ArpHandleTrap1F(TrapFrame); HandleTrap1F(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2F: case 0x2F:
/* Software Interrupt at DISPATCH level */ /* Software Interrupt at DISPATCH level */
ArpHandleTrap2F(TrapFrame); HandleTrap2F(TrapFrame);
break; break;
case 0xE1: case 0xE1:
/* InterProcessor Interrupt (IPI) */ /* InterProcessor Interrupt (IPI) */
ArpHandleTrapE1(TrapFrame); HandleTrapE1(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
/**
* Handles a 32-bit system call.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL XTCDECL
VOID VOID
ArpHandleSystemCall32(VOID) Traps::HandleSystemCall32(VOID)
{ {
DebugPrint(L"Handled 32-bit system call!\n"); 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 XTCDECL
VOID VOID
ArpHandleSystemCall64(VOID) Traps::HandleSystemCall64(VOID)
{ {
DebugPrint(L"Handled 64-bit system call!\n"); DebugPrint(L"Handled 64-bit system call!\n");
} }
@@ -155,7 +173,7 @@ ArpHandleSystemCall64(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -173,7 +191,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -191,7 +209,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -209,7 +227,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -227,7 +245,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -245,7 +263,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -263,7 +281,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -281,7 +299,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -299,7 +317,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -317,7 +335,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -335,7 +353,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -353,7 +371,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -371,7 +389,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -389,7 +407,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -407,7 +425,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -425,7 +443,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -443,7 +461,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -461,7 +479,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -479,7 +497,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -497,7 +515,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n"); DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n");
} }
@@ -514,7 +532,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -532,7 +550,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -550,7 +568,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n"); DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n");
} }
@@ -567,7 +585,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n"); DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n");
} }
@@ -584,8 +602,49 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); 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 * @since XT 1.0
*/ */
.macro ArpCreateTrapHandler Vector .macro ArCreateTrapHandler Vector
.global _ArpTrap\Vector .global _ArTrap\Vector
_ArpTrap\Vector: _ArTrap\Vector:
/* Push fake error code for non-error vectors */ /* 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 .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0 push $0
@@ -84,7 +84,7 @@ KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
push %esp push %esp
cld cld
call _ArpDispatchTrap call _ArDispatchTrap
/* Clean up the stack */ /* Clean up the stack */
add $4, %esp add $4, %esp
@@ -121,6 +121,6 @@ KernelModeReturn$\Vector:
/* Populate common trap handlers */ /* Populate common trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .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 .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
.endr .endr

View File

@@ -1,14 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ar/i686/cpufunc.c * FILE: xtoskrnl/ar/i686/cpufunc.cc
* DESCRIPTION: Routines to provide access to special i686 CPU instructions * DESCRIPTION: Routines to provide access to special i686 CPU instructions
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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. * Instructs the processor to clear the interrupt flag.
* *
@@ -18,7 +22,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArClearInterruptFlag(VOID) CpuFunc::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArCpuId(IN OUT PCPUID_REGISTERS Registers) CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,7 +80,7 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
ArFlushTlb(VOID) CpuFunc::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
ArWriteControlRegister(3, ArReadControlRegister(3)); ArWriteControlRegister(3, ArReadControlRegister(3));
@@ -91,7 +95,7 @@ ArFlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID) CpuFunc::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +120,7 @@ ArGetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArGetStackPointer(VOID) CpuFunc::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("mov %%esp, %%eax\n" __asm__ volatile("mov %%esp, %%eax\n"
@@ -135,7 +139,7 @@ ArGetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArHalt(VOID) CpuFunc::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,12 +153,12 @@ ArHalt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
ArInterruptsEnabled(VOID) CpuFunc::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
/* Get RFLAGS register */ /* Get RFLAGS register */
Flags = ArGetCpuFlags(); Flags = GetCpuFlags();
/* Check if interrupts are enabled and return result */ /* Check if interrupts are enabled and return result */
return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE;
@@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArInvalidateTlbEntry(PVOID Address) CpuFunc::InvalidateTlbEntry(PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +196,7 @@ ArInvalidateTlbEntry(PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadGlobalDescriptorTable(IN PVOID Source) CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadInterruptDescriptorTable(IN PVOID Source) CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadLocalDescriptorTable(IN USHORT Source) CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -254,7 +258,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadSegment(IN USHORT Segment, CpuFunc::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
@@ -316,7 +320,7 @@ ArLoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArLoadTaskRegister(USHORT Source) CpuFunc::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -332,7 +336,7 @@ ArLoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
ArMemoryBarrier(VOID) CpuFunc::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("xchg %%eax, %0" __asm__ volatile("xchg %%eax, %0"
@@ -353,7 +357,7 @@ ArMemoryBarrier(VOID)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadControlRegister(IN USHORT ControlRegister) CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -410,7 +414,7 @@ ArReadControlRegister(IN USHORT ControlRegister)
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
ArReadDebugRegister(IN USHORT DebugRegister) CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -479,7 +483,7 @@ ArReadDebugRegister(IN USHORT DebugRegister)
*/ */
XTCDECL XTCDECL
ULONG ULONG
ArReadFSDualWord(ULONG Offset) CpuFunc::ReadFSDualWord(ULONG Offset)
{ {
ULONG Value; ULONG Value;
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]" __asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
@@ -500,7 +504,7 @@ ArReadFSDualWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadModelSpecificRegister(IN ULONG Register) CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -519,7 +523,7 @@ ArReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
ArReadMxCsrRegister(VOID) CpuFunc::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -533,7 +537,7 @@ ArReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
ArReadTimeStampCounter(VOID) CpuFunc::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -552,7 +556,7 @@ ArReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArReadWriteBarrier(VOID) CpuFunc::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -569,7 +573,7 @@ ArReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArSetInterruptFlag(VOID) CpuFunc::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -586,7 +590,7 @@ ArSetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreGlobalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -606,7 +610,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreInterruptDescriptorTable(OUT PVOID Destination) CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -626,7 +630,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreLocalDescriptorTable(OUT PVOID Destination) CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -649,7 +653,7 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreSegment(IN USHORT Segment, CpuFunc::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
@@ -696,7 +700,7 @@ ArStoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
ArStoreTaskRegister(OUT PVOID Destination) CpuFunc::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -719,7 +723,7 @@ ArStoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteControlRegister(IN USHORT ControlRegister, CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
@@ -771,7 +775,7 @@ ArWriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteDebugRegister(IN USHORT DebugRegister, CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
@@ -840,7 +844,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteEflagsRegister(IN UINT_PTR Value) CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -863,7 +867,7 @@ ArWriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
ArWriteModelSpecificRegister(IN ULONG Register, CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
__asm__ volatile("wrmsr" __asm__ volatile("wrmsr"
@@ -881,10 +885,185 @@ ArWriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
ArYieldProcessor(VOID) CpuFunc::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :
: :
: "memory"); : "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 * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: I686 processor functionality support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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 * @since XT 1.0
*/ */
XTAPI PVOID ProcSup::GetBootStack(VOID)
VOID
ArInitializeProcessor(IN PVOID ProcessorStructures)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; return (PVOID)BootStack;
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);
} }
/** /**
@@ -123,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpIdentifyProcessor(VOID) ProcSup::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -141,7 +53,7 @@ ArpIdentifyProcessor(VOID)
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* 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[0] = CpuRegisters.Ebx;
*(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx;
*(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx;
@@ -190,6 +102,77 @@ ArpIdentifyProcessor(VOID)
/* TODO: Store a list of CPU features in processor control block */ /* 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). * Initializes the kernel's Global Descriptor Table (GDT).
* *
@@ -202,23 +185,23 @@ ArpIdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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); SetGdtEntry(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_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 XTAPI
VOID VOID
ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -241,34 +224,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++) for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{ {
/* Set the IDT to handle unexpected interrupts */ /* 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 */ /* Setup IDT handlers for known interrupts and traps */
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, 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, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
} }
/** /**
@@ -292,7 +275,7 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
@@ -303,7 +286,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb;
/* Set GDT, IDT and TSS descriptors */ /* Set GDT, IDT and TSS descriptors */
ProcessorBlock->GdtBase = Gdt; ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt;
ProcessorBlock->IdtBase = Idt; ProcessorBlock->IdtBase = Idt;
ProcessorBlock->TssBase = Tss; ProcessorBlock->TssBase = Tss;
@@ -320,10 +303,10 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Set process and thread information */ /* Set process and thread information */
ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &(KE::KProcess::GetInitialProcess())->ProcessControlBlock;
ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.IdleThread = &(KE::KThread::GetInitialThread())->ThreadControlBlock;
ProcessorBlock->Prcb.NextThread = NULL; ProcessorBlock->Prcb.NextThread = nullptr;
/* Set initial runlevel */ /* Set initial runlevel */
ProcessorBlock->RunLevel = PASSIVE_LEVEL; ProcessorBlock->RunLevel = PASSIVE_LEVEL;
@@ -338,13 +321,13 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorRegisters(VOID) ProcSup::InitializeProcessorRegisters(VOID)
{ {
/* Clear EFLAGS register */ /* Clear EFLAGS register */
ArWriteEflagsRegister(0); CpuFunc::WriteEflagsRegister(0);
/* Enable write-protection */ /* Enable write-protection */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP);
} }
/** /**
@@ -374,7 +357,7 @@ ArpInitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
@@ -394,15 +377,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*KernelFaultStack = (PVOID)Address; *KernelFaultStack = (PVOID)Address;
/* Assign a space for GDT and advance */ /* Assign a space for GDT and advance */
*Gdt = (PVOID)Address; *Gdt = (PKGDTENTRY)(PVOID)Address;
Address += sizeof(ArInitialGdt); Address += sizeof(ArInitialGdt);
/* Assign a space for Processor Block and advance */ /* Assign a space for Processor Block and advance */
*ProcessorBlock = (PVOID)Address; *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address;
Address += sizeof(ArInitialProcessorBlock); Address += sizeof(ArInitialProcessorBlock);
/* Assign a space for TSS */ /* Assign a space for TSS */
*Tss = (PVOID)Address; *Tss = (PKTSS)(PVOID)Address;
} }
/** /**
@@ -414,13 +397,13 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeSegments(VOID) ProcSup::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
ArLoadSegment(SEGMENT_FS, KGDT_R0_PB); CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
} }
/** /**
@@ -435,7 +418,7 @@ ArpInitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
@@ -468,8 +451,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
/* Initialize task gates for DoubleFault and NMI traps */ /* Initialize task gates for DoubleFault and NMI traps */
ArpSetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack);
ArpSetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack);
} }
/** /**
@@ -484,7 +467,7 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
@@ -498,20 +481,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS;
/* Initialize DoubleFault TSS and set initial state */ /* Initialize DoubleFault TSS and set initial state */
Tss = (PKTSS)ArpDoubleFaultTss; Tss = (PKTSS)DoubleFaultTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap08); Tss->Eip = PtrToUlong(ArTrap0x08);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; Tss->Fs = KGDT_R0_PB;
Tss->Ss0 = KGDT_R0_DATA; 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 */ /* Setup DoubleFault TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)]));
@@ -555,7 +538,7 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt, ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
@@ -601,6 +584,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
GdtEntry->Bits.Type = (Type & 0x1F); 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. * Fills in a call, interrupt, task or trap gate entry.
* *
@@ -628,7 +644,7 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetIdtGate(IN PKIDTENTRY Idt, ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
@@ -654,7 +670,7 @@ ArpSetIdtGate(IN PKIDTENTRY Idt,
*/ */
XTAPI XTAPI
VOID VOID
ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
@@ -668,19 +684,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS;
/* Initialize NMI TSS and set initial state */ /* Initialize NMI TSS and set initial state */
Tss = (PKTSS)ArpNonMaskableInterruptTss; Tss = (PKTSS)NonMaskableInterruptTss;
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = KGDT_R0_LDT; Tss->LDT = KGDT_R0_LDT;
Tss->CR3 = ArReadControlRegister(3); Tss->CR3 = ArReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArpHandleTrap02); Tss->Eip = PtrToUlong(ArTrap0x02);
Tss->Cs = KGDT_R0_CODE; Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Fs = KGDT_R0_PB; 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 */ /* Setup NMI TSS entry in Global Descriptor Table */
TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)]));
@@ -693,3 +709,24 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
TssEntry->Bits.Present = 1; TssEntry->Bits.Present = 1;
TssEntry->Bits.Type = I686_TSS; 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 * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * 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 * DESCRIPTION: I686 system traps
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * 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. * Dispatches the trap provided by common trap handler.
* *
@@ -21,110 +25,110 @@
*/ */
XTCDECL XTCDECL
VOID VOID
ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame)
{ {
/* Check vector and call appropriate handler */ /* Check vector and call appropriate handler */
switch(TrapFrame->Vector) switch(TrapFrame->Vector)
{ {
case 0x00: case 0x00:
/* Divide By Zero exception */ /* Divide By Zero exception */
ArpHandleTrap00(TrapFrame); HandleTrap00(TrapFrame);
break; break;
case 0x01: case 0x01:
/* Debug exception */ /* Debug exception */
ArpHandleTrap01(TrapFrame); HandleTrap01(TrapFrame);
break; break;
case 0x02: case 0x02:
/* Non-Maskable Interrupt (NMI) */ /* Non-Maskable Interrupt (NMI) */
ArpHandleTrap02(TrapFrame); HandleTrap02(TrapFrame);
break; break;
case 0x03: case 0x03:
/* INT3 instruction executed */ /* INT3 instruction executed */
ArpHandleTrap03(TrapFrame); HandleTrap03(TrapFrame);
break; break;
case 0x04: case 0x04:
/* Overflow exception */ /* Overflow exception */
ArpHandleTrap04(TrapFrame); HandleTrap04(TrapFrame);
break; break;
case 0x05: case 0x05:
/* Bound Range Exceeded exception */ /* Bound Range Exceeded exception */
ArpHandleTrap05(TrapFrame); HandleTrap05(TrapFrame);
break; break;
case 0x06: case 0x06:
/* Invalid Opcode exception */ /* Invalid Opcode exception */
ArpHandleTrap06(TrapFrame); HandleTrap06(TrapFrame);
break; break;
case 0x07: case 0x07:
/* Device Not Available exception */ /* Device Not Available exception */
ArpHandleTrap07(TrapFrame); HandleTrap07(TrapFrame);
break; break;
case 0x08: case 0x08:
/* Double Fault exception */ /* Double Fault exception */
ArpHandleTrap08(TrapFrame); HandleTrap08(TrapFrame);
break; break;
case 0x09: case 0x09:
/* Segment Overrun exception */ /* Segment Overrun exception */
ArpHandleTrap09(TrapFrame); HandleTrap09(TrapFrame);
break; break;
case 0x0A: case 0x0A:
/* Invalid TSS exception */ /* Invalid TSS exception */
ArpHandleTrap0A(TrapFrame); HandleTrap0A(TrapFrame);
break; break;
case 0x0B: case 0x0B:
/* Segment Not Present exception */ /* Segment Not Present exception */
ArpHandleTrap0B(TrapFrame); HandleTrap0B(TrapFrame);
break; break;
case 0x0C: case 0x0C:
/* Stack Segment Fault exception */ /* Stack Segment Fault exception */
ArpHandleTrap0C(TrapFrame); HandleTrap0C(TrapFrame);
break; break;
case 0x0D: case 0x0D:
/* General Protection Fault (GPF) exception*/ /* General Protection Fault (GPF) exception*/
ArpHandleTrap0D(TrapFrame); HandleTrap0D(TrapFrame);
break; break;
case 0x0E: case 0x0E:
/* Page Fault exception */ /* Page Fault exception */
ArpHandleTrap0E(TrapFrame); HandleTrap0E(TrapFrame);
break; break;
case 0x10: case 0x10:
/* X87 Floating-Point exception */ /* X87 Floating-Point exception */
ArpHandleTrap10(TrapFrame); HandleTrap10(TrapFrame);
break; break;
case 0x11: case 0x11:
/* Alignment Check exception */ /* Alignment Check exception */
ArpHandleTrap11(TrapFrame); HandleTrap11(TrapFrame);
break; break;
case 0x12: case 0x12:
/* Machine Check exception */ /* Machine Check exception */
ArpHandleTrap12(TrapFrame); HandleTrap12(TrapFrame);
break; break;
case 0x13: case 0x13:
/* SIMD Floating-Point exception */ /* SIMD Floating-Point exception */
ArpHandleTrap13(TrapFrame); HandleTrap13(TrapFrame);
break; break;
case 0x2A: case 0x2A:
/* Tick Count service request */ /* Tick Count service request */
ArpHandleTrap2A(TrapFrame); HandleTrap2A(TrapFrame);
break; break;
case 0x2B: case 0x2B:
/* User-mode callback return */ /* User-mode callback return */
ArpHandleTrap2B(TrapFrame); HandleTrap2B(TrapFrame);
break; break;
case 0x2C: case 0x2C:
/* Assertion raised */ /* Assertion raised */
ArpHandleTrap2C(TrapFrame); HandleTrap2C(TrapFrame);
break; break;
case 0x2D: case 0x2D:
/* Debug-Service-Request raised */ /* Debug-Service-Request raised */
ArpHandleTrap2D(TrapFrame); HandleTrap2D(TrapFrame);
break; break;
case 0x2E: case 0x2E:
/* System call service request */ /* System call service request */
ArpHandleTrap2E(TrapFrame); HandleTrap2E(TrapFrame);
break; break;
default: default:
/* Unknown/Unexpected trap */ /* Unknown/Unexpected trap */
ArpHandleTrapFF(TrapFrame); HandleTrapFF(TrapFrame);
break; break;
} }
} }
@@ -141,7 +145,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n");
for(;;); for(;;);
@@ -159,7 +163,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug exception (0x01)!\n"); DebugPrint(L"Handled Debug exception (0x01)!\n");
for(;;); for(;;);
@@ -177,7 +181,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n");
for(;;); for(;;);
@@ -195,7 +199,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled INT3 (0x03)!\n"); DebugPrint(L"Handled INT3 (0x03)!\n");
for(;;); for(;;);
@@ -213,7 +217,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Overflow exception (0x04)!\n"); DebugPrint(L"Handled Overflow exception (0x04)!\n");
for(;;); for(;;);
@@ -231,7 +235,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n");
for(;;); for(;;);
@@ -249,7 +253,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n");
for(;;); for(;;);
@@ -267,7 +271,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); DebugPrint(L"Handled Device Not Available exception (0x07)!\n");
for(;;); for(;;);
@@ -285,7 +289,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); DebugPrint(L"Handled Double-Fault exception (0x08)!\n");
for(;;); for(;;);
@@ -303,7 +307,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n");
for(;;); for(;;);
@@ -321,7 +325,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n");
for(;;); for(;;);
@@ -339,7 +343,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n");
for(;;); for(;;);
@@ -357,7 +361,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n");
for(;;); for(;;);
@@ -375,7 +379,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n");
for(;;); for(;;);
@@ -393,7 +397,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); DebugPrint(L"Handled Page-Fault exception (0x0E)!\n");
for(;;); for(;;);
@@ -411,7 +415,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n");
for(;;); for(;;);
@@ -429,7 +433,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); DebugPrint(L"Handled Alignment-Check exception (0x11)!\n");
for(;;); for(;;);
@@ -447,7 +451,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); DebugPrint(L"Handled Machine-Check exception (0x12)!\n");
for(;;); for(;;);
@@ -465,7 +469,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n");
for(;;); for(;;);
@@ -483,7 +487,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n"); DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n");
} }
@@ -500,7 +504,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled Callback return service request (0x2B)!\n"); DebugPrint(L"Unhandled Callback return service request (0x2B)!\n");
} }
@@ -517,7 +521,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Assertion (0x2C)!\n"); DebugPrint(L"Handled Assertion (0x2C)!\n");
for(;;); for(;;);
@@ -535,7 +539,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n");
for(;;); for(;;);
@@ -553,7 +557,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Unhandled system call (0x2E)!\n"); DebugPrint(L"Unhandled system call (0x2E)!\n");
} }
@@ -570,8 +574,28 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame)
*/ */
XTCDECL XTCDECL
VOID VOID
ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
{ {
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
for(;;); 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 * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/rundown.c * FILE: xtoskrnl/ex/rundown.cc
* DESCRIPTION: Rundown protection mechanism * DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Executive */
namespace EX
{
/** /**
* Acquires the rundown protection for given descriptor. * Acquires the rundown protection for given descriptor.
* *
@@ -21,7 +25,7 @@
*/ */
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
@@ -69,7 +73,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
} }
@@ -86,7 +90,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
/* Reset descriptor counter */ /* Reset descriptor counter */
Descriptor->Count = 0; Descriptor->Count = 0;
@@ -104,7 +108,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, NULL); RtlAtomicExchangePointer(&Descriptor->Ptr, NULL);
} }
@@ -121,7 +125,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
PEX_RUNDOWN_WAIT_BLOCK WaitBlock; PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
@@ -136,7 +140,7 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count)) if(!RtlAtomicDecrement64((PLONG_PTR)&WaitBlock->Count))
{ {
KeSetEvent(&WaitBlock->WakeEvent, 0, FALSE); KE::Event::SetEvent(&WaitBlock->WakeEvent, 0, FALSE);
} }
break; break;
@@ -172,7 +176,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
} /* namespace */

View File

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

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI XTAPI
VOID VOID
KepSwitchBootStack(IN ULONG_PTR Stack); KepSwitchBootStack();
#endif /* __XTOSKRNL_AMD64_KEI_H */ #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 VOID
ArFlushTlb(VOID); ArFlushTlb(VOID);
XTAPI
PVOID
ArGetBootStack(VOID);
XTCDECL XTCDECL
ULONG ULONG
ArGetCpuFlags(VOID); ArGetCpuFlags(VOID);

View File

@@ -55,6 +55,6 @@ KepStartKernel(VOID);
XTAPI XTAPI
VOID VOID
KepSwitchBootStack(IN ULONG_PTR Stack); KepSwitchBootStack();
#endif /* __XTOSKRNL_I686_KEI_H */ #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 */

View File

@@ -13,6 +13,10 @@
/* Kernel services routines forward references */ /* Kernel services routines forward references */
XTAPI
PKERNEL_INITIALIZATION_BLOCK
KeGetInitializationBlock(VOID);
XTAPI XTAPI
VOID VOID
KeClearEvent(IN PKEVENT Event); KeClearEvent(IN PKEVENT Event);

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,15 +1,18 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/sysres.c * FILE: xtoskrnl/ke/sysres.cc
* DESCRIPTION: System resources management; This code is based on the MinocaOS implementation * DESCRIPTION: System resources management; This code is based on the MinocaOS implementation
* Copyright(C) 2012 Minoca Corp. (https://github.com/minoca/os/blob/master/kernel/ke/sysres.c)
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
/* Kernel Library */
namespace KE
{
/** /**
* Looks for an unacquired system resource of the specified type and acquires it. * Looks for an unacquired system resource of the specified type and acquires it.
* *
@@ -25,59 +28,11 @@
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, SystemResources::AcquireResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{ {
/* Get system resource and acquire an ownership */ /* Get system resource and acquire an ownership */
return KepGetSystemResource(ResourceType, TRUE, ResourceHeader); return GetSystemResource(ResourceType, TRUE, ResourceHeader);
}
/**
* Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.
*
* @param ResourceType
* Supplies system resource type.
*
* @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{
/* Get system resource without acquiring an ownership */
return KepGetSystemResource(ResourceType, FALSE, ResourceHeader);
}
/**
* Releases system resource.
*
* @param ResourceHeader
* Specifies a pointer to the system resource header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
{
/* Disable interrupts and acquire a spinlock */
ArClearInterruptFlag();
KeAcquireSpinLock(&KepSystemResourcesLock);
/* Release resource lock */
ResourceHeader->ResourceLocked = FALSE;
/* Release spinlock and enable interrupts */
KeReleaseSpinLock(&KepSystemResourcesLock);
ArSetInterruptFlag();
} }
/** /**
@@ -98,7 +53,7 @@ KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
*/ */
XTAPI XTAPI
XTSTATUS XTSTATUS
KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
IN BOOLEAN ResourceLock, IN BOOLEAN ResourceLock,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader) OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{ {
@@ -111,15 +66,15 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
/* Check if interrupts are enabled */ /* Check if interrupts are enabled */
Interrupts = ArInterruptsEnabled(); Interrupts = AR::CpuFunc::InterruptsEnabled();
/* Disable interrupts and acquire a spinlock */ /* Disable interrupts and acquire a spinlock */
ArClearInterruptFlag(); AR::CpuFunc::ClearInterruptFlag();
KeAcquireSpinLock(&KepSystemResourcesLock); SpinLock::AcquireSpinLock(&ResourcesLock);
/* Iterate through system resources list */ /* Iterate through system resources list */
ListEntry = KepSystemResourcesListHead.Flink; ListEntry = ResourcesListHead.Flink;
while(ListEntry != &KepSystemResourcesListHead) while(ListEntry != &ResourcesListHead)
{ {
/* Get resource header */ /* Get resource header */
Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); Resource = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
@@ -151,19 +106,19 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
} }
/* Check if resource was found */ /* Check if resource was found */
if(ListEntry == &KepSystemResourcesListHead) if(ListEntry == &ResourcesListHead)
{ {
/* Resource not found, return NULL */ /* Resource not found, return NULL */
Resource = NULL; Resource = nullptr;
Status = STATUS_NOT_FOUND; Status = STATUS_NOT_FOUND;
} }
/* Release spinlock and re-enable interrupts if necessary */ /* Release spinlock and re-enable interrupts if necessary */
KeReleaseSpinLock(&KepSystemResourcesLock); SpinLock::ReleaseSpinLock(&ResourcesLock);
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
ArSetInterruptFlag(); AR::CpuFunc::SetInterruptFlag();
} }
/* Return resource header and status code */ /* Return resource header and status code */
@@ -171,6 +126,28 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
return Status; return Status;
} }
/**
* Looks for an unacquired system resource of the specified type and returns it without acquiring an ownership.
*
* @param ResourceType
* Supplies system resource type.
*
* @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader)
{
/* Get system resource without acquiring an ownership */
return GetSystemResource(ResourceType, FALSE, ResourceHeader);
}
/** /**
* Initializes system resource management. * Initializes system resource management.
* *
@@ -180,22 +157,22 @@ KepGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
*/ */
XTAPI XTAPI
VOID VOID
KepInitializeSystemResources(VOID) SystemResources::InitializeResources(VOID)
{ {
PSYSTEM_RESOURCE_HEADER ResourceHeader; PSYSTEM_RESOURCE_HEADER ResourceHeader;
PLIST_ENTRY ListEntry, NextListEntry; PLIST_ENTRY ListEntry, NextListEntry;
ULONG ResourceSize; ULONG ResourceSize;
/* Initialize system resources spin lock and resource list */ /* Initialize system resources spin lock and resource list */
KeInitializeSpinLock(&KepSystemResourcesLock); SpinLock::InitializeSpinLock(&ResourcesLock);
RtlInitializeListHead(&KepSystemResourcesListHead); RtlInitializeListHead(&ResourcesListHead);
/* Make sure there are some system resources available */ /* Make sure there are some system resources available */
if(!RtlListEmpty(&KeInitializationBlock->SystemResourcesListHead)) if(!RtlListEmpty(BootInformation::GetSystemResources()))
{ {
/* Iterate through system resources list */ /* Iterate through system resources list */
ListEntry = KeInitializationBlock->SystemResourcesListHead.Flink; ListEntry = BootInformation::GetSystemResources()->Flink;
while(ListEntry != &KeInitializationBlock->SystemResourcesListHead) while(ListEntry != BootInformation::GetSystemResources())
{ {
/* Get resource header and next list entry */ /* Get resource header and next list entry */
ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry); ResourceHeader = CONTAIN_RECORD(ListEntry, SYSTEM_RESOURCE_HEADER, ListEntry);
@@ -223,7 +200,7 @@ KepInitializeSystemResources(VOID)
{ {
/* Move valid resource to the internal kernel list of system resources */ /* Move valid resource to the internal kernel list of system resources */
RtlRemoveEntryList(&ResourceHeader->ListEntry); RtlRemoveEntryList(&ResourceHeader->ListEntry);
RtlInsertTailList(&KepSystemResourcesListHead, &ResourceHeader->ListEntry); RtlInsertTailList(&ResourcesListHead, &ResourceHeader->ListEntry);
} }
/* Go to the next list entry */ /* Go to the next list entry */
@@ -231,3 +208,31 @@ KepInitializeSystemResources(VOID)
} }
} }
} }
/**
* Releases boot system resource.
*
* @param ResourceHeader
* Specifies a pointer to the boot system resource header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
{
/* Disable interrupts and acquire a spinlock */
AR::CpuFunc::ClearInterruptFlag();
SpinLock::AcquireSpinLock(&ResourcesLock);
/* Release resource lock */
ResourceHeader->ResourceLocked = FALSE;
/* Release spinlock and enable interrupts */
SpinLock::ReleaseSpinLock(&ResourcesLock);
AR::CpuFunc::SetInterruptFlag();
}
} /* namespace */

View File

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

View File

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

View File

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