From c8dc2a1407c39f1ce56ae9312ced1833b4d1b0bc Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Mon, 8 Sep 2025 15:29:13 +0200 Subject: [PATCH] Migrate AR subsystem to C++ --- sdk/cmake/toolchain.cmake | 3 +- sdk/xtbk/README.md | 13 - sdk/xtdk/amd64/arfuncs.h | 7 + sdk/xtdk/amd64/hlfuncs.h | 6 + sdk/xtdk/blfuncs.h | 1 + sdk/xtdk/exfuncs.h | 6 + sdk/xtdk/hlfuncs.h | 2 + sdk/xtdk/i686/arfuncs.h | 6 + sdk/xtdk/i686/hlfuncs.h | 6 + sdk/xtdk/kefuncs.h | 24 + sdk/xtdk/xtblapi.h | 1 + sdk/xtdk/xtcompat.h | 21 + sdk/xtdk/xtkmapi.h | 1 + sdk/xtdk/xttypes.h | 3 +- xtoskrnl/CMakeLists.txt | 9 +- xtoskrnl/ar/amd64/archsup.S | 10 +- xtoskrnl/ar/amd64/{cpufunc.c => cpufunc.cc} | 275 +++++++++-- xtoskrnl/ar/amd64/data.cc | 34 ++ xtoskrnl/ar/amd64/globals.c | 28 -- xtoskrnl/ar/amd64/{procsup.c => procsup.cc} | 491 +++++++++++--------- xtoskrnl/ar/amd64/{traps.c => traps.cc} | 169 ++++--- xtoskrnl/ar/i686/archsup.S | 10 +- xtoskrnl/ar/i686/{cpufunc.c => cpufunc.cc} | 259 +++++++++-- xtoskrnl/ar/i686/data.cc | 40 ++ xtoskrnl/ar/i686/globals.c | 32 -- xtoskrnl/ar/i686/{procsup.c => procsup.cc} | 425 +++++++++-------- xtoskrnl/ar/i686/{traps.c => traps.cc} | 130 +++--- xtoskrnl/includes/amd64/ari.h | 8 + xtoskrnl/includes/amd64/kei.h | 2 +- xtoskrnl/includes/ar.hh | 18 + xtoskrnl/includes/ar/amd64/cpufunc.hh | 62 +++ xtoskrnl/includes/ar/amd64/procsup.hh | 71 +++ xtoskrnl/includes/ar/amd64/traps.hh | 180 +++++++ xtoskrnl/includes/ar/i686/cpufunc.hh | 61 +++ xtoskrnl/includes/ar/i686/procsup.hh | 79 ++++ xtoskrnl/includes/ar/i686/traps.hh | 177 +++++++ xtoskrnl/includes/i686/ari.h | 4 + xtoskrnl/includes/i686/kei.h | 2 +- xtoskrnl/includes/xtos.hh | 29 ++ xtoskrnl/ke/amd64/krnlinit.c | 14 +- xtoskrnl/ke/i686/krnlinit.c | 14 +- xtoskrnl/ke/krnlinit.c | 4 +- 42 files changed, 2042 insertions(+), 695 deletions(-) delete mode 100644 sdk/xtbk/README.md create mode 100644 sdk/xtdk/xtcompat.h rename xtoskrnl/ar/amd64/{cpufunc.c => cpufunc.cc} (83%) create mode 100644 xtoskrnl/ar/amd64/data.cc delete mode 100644 xtoskrnl/ar/amd64/globals.c rename xtoskrnl/ar/amd64/{procsup.c => procsup.cc} (54%) rename xtoskrnl/ar/amd64/{traps.c => traps.cc} (75%) rename xtoskrnl/ar/i686/{cpufunc.c => cpufunc.cc} (83%) create mode 100644 xtoskrnl/ar/i686/data.cc delete mode 100644 xtoskrnl/ar/i686/globals.c rename xtoskrnl/ar/i686/{procsup.c => procsup.cc} (62%) rename xtoskrnl/ar/i686/{traps.c => traps.cc} (80%) create mode 100644 xtoskrnl/includes/ar.hh create mode 100644 xtoskrnl/includes/ar/amd64/cpufunc.hh create mode 100644 xtoskrnl/includes/ar/amd64/procsup.hh create mode 100644 xtoskrnl/includes/ar/amd64/traps.hh create mode 100644 xtoskrnl/includes/ar/i686/cpufunc.hh create mode 100644 xtoskrnl/includes/ar/i686/procsup.hh create mode 100644 xtoskrnl/includes/ar/i686/traps.hh create mode 100644 xtoskrnl/includes/xtos.hh diff --git a/sdk/cmake/toolchain.cmake b/sdk/cmake/toolchain.cmake index 2d72ec6..051e5c6 100644 --- a/sdk/cmake/toolchain.cmake +++ b/sdk/cmake/toolchain.cmake @@ -20,8 +20,9 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_C_STANDARD 23) set(CMAKE_CXX_STANDARD 23) -# Disable standard C libraries +# Disable standard C and C++ libraries set(CMAKE_C_STANDARD_LIBRARIES "" CACHE INTERNAL "") +set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE INTERNAL "") # Clean linker flags set(CMAKE_STATIC_LINKER_FLAGS "") diff --git a/sdk/xtbk/README.md b/sdk/xtbk/README.md deleted file mode 100644 index b5882a1..0000000 --- a/sdk/xtbk/README.md +++ /dev/null @@ -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. diff --git a/sdk/xtdk/amd64/arfuncs.h b/sdk/xtdk/amd64/arfuncs.h index 72a9d2c..de5ad71 100644 --- a/sdk/xtdk/amd64/arfuncs.h +++ b/sdk/xtdk/amd64/arfuncs.h @@ -16,30 +16,37 @@ /* Routines used by XTLDR */ +XTCLINK XTCDECL VOID ArClearInterruptFlag(VOID); +XTCLINK XTCDECL BOOLEAN ArCpuId(IN OUT PCPUID_REGISTERS Registers); +XTCLINK XTCDECL VOID ArEnableExtendedPhysicalAddressing(IN ULONG_PTR PageMap); +XTCLINK XTCDECL VOID ArHalt(VOID); +XTCLINK XTCDECL ULONG_PTR ArReadControlRegister(IN USHORT ControlRegister); +XTCLINK XTCDECL ULONGLONG ArReadModelSpecificRegister(IN ULONG Register); +XTCLINK XTCDECL VOID ArWriteControlRegister(IN USHORT ControlRegister, diff --git a/sdk/xtdk/amd64/hlfuncs.h b/sdk/xtdk/amd64/hlfuncs.h index d5d6bff..44eeaab 100644 --- a/sdk/xtdk/amd64/hlfuncs.h +++ b/sdk/xtdk/amd64/hlfuncs.h @@ -16,28 +16,34 @@ /* HAL library routines forward references */ +XTCLINK XTCDECL UCHAR HlIoPortInByte(IN USHORT Port); +XTCLINK XTCDECL ULONG HlIoPortInLong(IN USHORT Port); +XTCLINK XTCDECL USHORT HlIoPortInShort(IN USHORT Port); +XTCLINK XTCDECL VOID HlIoPortOutByte(IN USHORT Port, IN UCHAR Data); +XTCLINK XTCDECL VOID HlIoPortOutLong(IN USHORT Port, IN ULONG Value); +XTCLINK XTCDECL VOID HlIoPortOutShort(IN USHORT Port, diff --git a/sdk/xtdk/blfuncs.h b/sdk/xtdk/blfuncs.h index 77e0bf1..6dc2bad 100644 --- a/sdk/xtdk/blfuncs.h +++ b/sdk/xtdk/blfuncs.h @@ -14,6 +14,7 @@ /* XT BootLoader routines forward references */ +XTCLINK XTCDECL EFI_STATUS BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable, diff --git a/sdk/xtdk/exfuncs.h b/sdk/xtdk/exfuncs.h index 8928661..6c42959 100644 --- a/sdk/xtdk/exfuncs.h +++ b/sdk/xtdk/exfuncs.h @@ -14,26 +14,32 @@ /* Kernel Executive routines forward references */ +XTCLINK XTFASTCALL BOOLEAN ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor); +XTCLINK XTFASTCALL VOID ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor); diff --git a/sdk/xtdk/hlfuncs.h b/sdk/xtdk/hlfuncs.h index 43de6a4..0dce06d 100644 --- a/sdk/xtdk/hlfuncs.h +++ b/sdk/xtdk/hlfuncs.h @@ -15,11 +15,13 @@ /* Routines used by XTLDR */ +XTCLINK XTCDECL XTSTATUS HlComPortPutByte(IN PCPPORT Port, IN UCHAR Byte); +XTCLINK XTCDECL XTSTATUS HlInitializeComPort(IN OUT PCPPORT Port, diff --git a/sdk/xtdk/i686/arfuncs.h b/sdk/xtdk/i686/arfuncs.h index 8c48bb5..84ea40c 100644 --- a/sdk/xtdk/i686/arfuncs.h +++ b/sdk/xtdk/i686/arfuncs.h @@ -16,26 +16,32 @@ /* Routines used by XTLDR */ +XTCLINK XTCDECL VOID ArClearInterruptFlag(VOID); +XTCLINK XTCDECL BOOLEAN ArCpuId(IN OUT PCPUID_REGISTERS Registers); +XTCLINK XTCDECL VOID ArHalt(VOID); +XTCLINK XTCDECL ULONG_PTR ArReadControlRegister(IN USHORT ControlRegister); +XTCLINK XTCDECL ULONGLONG ArReadModelSpecificRegister(IN ULONG Register); +XTCLINK XTCDECL VOID ArWriteControlRegister(IN USHORT ControlRegister, diff --git a/sdk/xtdk/i686/hlfuncs.h b/sdk/xtdk/i686/hlfuncs.h index dfc35ac..33d0a93 100644 --- a/sdk/xtdk/i686/hlfuncs.h +++ b/sdk/xtdk/i686/hlfuncs.h @@ -16,28 +16,34 @@ /* HAL library routines forward references */ +XTCLINK XTCDECL UCHAR HlIoPortInByte(IN USHORT Port); +XTCLINK XTCDECL ULONG HlIoPortInLong(IN USHORT Port); +XTCLINK XTCDECL USHORT HlIoPortInShort(IN USHORT Port); +XTCLINK XTCDECL VOID HlIoPortOutByte(IN USHORT Port, IN UCHAR Data); +XTCLINK XTCDECL VOID HlIoPortOutLong(IN USHORT Port, IN ULONG Value); +XTCLINK XTCDECL VOID HlIoPortOutShort(IN USHORT Port, diff --git a/sdk/xtdk/kefuncs.h b/sdk/xtdk/kefuncs.h index 3dbb8ea..a531b72 100644 --- a/sdk/xtdk/kefuncs.h +++ b/sdk/xtdk/kefuncs.h @@ -16,36 +16,44 @@ /* Kernel services routines forward references */ +XTCLINK XTFASTCALL VOID KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); +XTCLINK XTFASTCALL VOID KeAcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTCLINK XTAPI XTSTATUS KeAcquireSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); +XTCLINK XTAPI BOOLEAN KeCancelTimer(IN PKTIMER Timer); +XTCLINK XTFASTCALL KRUNLEVEL KeGetCurrentRunLevel(VOID); +XTCLINK XTAPI XTSTATUS KeGetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType, OUT PSYSTEM_RESOURCE_HEADER *ResourceHeader); +XTCLINK XTAPI BOOLEAN KeGetTimerState(IN PKTIMER Timer); +XTCLINK XTAPI VOID KeInitializeApc(IN PKAPC Apc, @@ -57,45 +65,54 @@ KeInitializeApc(IN PKAPC Apc, IN KPROCESSOR_MODE ApcMode, IN PVOID Context); +XTCLINK XTAPI VOID KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DpcRoutine, IN PVOID DpcContext); +XTCLINK XTAPI VOID KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit); +XTCLINK XTAPI VOID KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock); +XTCLINK XTAPI VOID KeInitializeThreadedDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DpcRoutine, IN PVOID DpcContext); +XTCLINK XTAPI VOID KeInitializeTimer(OUT PKTIMER Timer, IN KTIMER_TYPE Type); +XTCLINK XTFASTCALL VOID KeLowerRunLevel(IN KRUNLEVEL RunLevel); +XTCLINK XTFASTCALL KRUNLEVEL KeRaiseRunLevel(IN KRUNLEVEL RunLevel); +XTCLINK XTAPI LONG KeReadSemaphoreState(IN PKSEMAPHORE Semaphore); +XTCLINK XTAPI LONG KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, @@ -103,23 +120,28 @@ KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Adjustment, IN BOOLEAN Wait); +XTCLINK XTFASTCALL VOID KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel); +XTCLINK XTFASTCALL VOID KeReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock); +XTCLINK XTAPI VOID KeReleaseSystemResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader); +XTCLINK XTAPI VOID KeSetTargetProcessorDpc(IN PKDPC Dpc, IN CCHAR Number); +XTCLINK XTAPI VOID KeSetTimer(IN PKTIMER Timer, @@ -127,10 +149,12 @@ KeSetTimer(IN PKTIMER Timer, IN LONG Period, IN PKDPC Dpc); +XTCLINK XTAPI VOID KeSignalCallDpcDone(IN PVOID SystemArgument); +XTCLINK XTAPI BOOLEAN KeSignalCallDpcSynchronize(IN PVOID SystemArgument); diff --git a/sdk/xtdk/xtblapi.h b/sdk/xtdk/xtblapi.h index 5d00676..b05daad 100644 --- a/sdk/xtdk/xtblapi.h +++ b/sdk/xtdk/xtblapi.h @@ -7,6 +7,7 @@ */ /* Base XT headers */ +#include #include #include #include diff --git a/sdk/xtdk/xtcompat.h b/sdk/xtdk/xtcompat.h new file mode 100644 index 0000000..b2a1c0e --- /dev/null +++ b/sdk/xtdk/xtcompat.h @@ -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 + */ + +#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 */ diff --git a/sdk/xtdk/xtkmapi.h b/sdk/xtdk/xtkmapi.h index d03d602..d6f1d20 100644 --- a/sdk/xtdk/xtkmapi.h +++ b/sdk/xtdk/xtkmapi.h @@ -7,6 +7,7 @@ */ /* Base XT headers */ +#include #include #include #include diff --git a/sdk/xtdk/xttypes.h b/sdk/xtdk/xttypes.h index 7bf5071..2e06866 100644 --- a/sdk/xtdk/xttypes.h +++ b/sdk/xtdk/xttypes.h @@ -10,6 +10,7 @@ #define __XTDK_XTTYPES_H #include +#include /* Standard C types */ @@ -128,7 +129,7 @@ typedef CHAR SZ, *PSZ; typedef const CHAR CSZ, *PCSZ; /* UNICODE character types */ -typedef USHORT WCHAR, *PWCHAR; +typedef wchar WCHAR, *PWCHAR; typedef WCHAR *PWCH, *LPWCH; typedef const WCHAR *PCWCH, *LPCWCH; typedef WCHAR *PWSTR, *LPWSTR, *NWPSTR; diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 5037c0e..e5be4a9 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -11,6 +11,7 @@ include_directories( list(APPEND LIBXTOS_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc ${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c ${XTOSKRNL_SOURCE_DIR}/rtl/globals.c @@ -25,10 +26,10 @@ list(APPEND LIBXTOS_SOURCE list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c - ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc ${XTOSKRNL_SOURCE_DIR}/ex/rundown.c ${XTOSKRNL_SOURCE_DIR}/hl/acpi.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c diff --git a/xtoskrnl/ar/amd64/archsup.S b/xtoskrnl/ar/amd64/archsup.S index 849df4f..7788fc0 100644 --- a/xtoskrnl/ar/amd64/archsup.S +++ b/xtoskrnl/ar/amd64/archsup.S @@ -22,9 +22,9 @@ * * @since XT 1.0 */ -.macro ArpCreateTrapHandler Vector -.global ArpTrap\Vector -ArpTrap\Vector: +.macro ArCreateTrapHandler Vector +.global ArTrap\Vector +ArTrap\Vector: /* Push fake error code for non-error vectors */ .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 push $0 @@ -113,7 +113,7 @@ KernelMode$\Vector: /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ mov %rsp, %rcx cld - call ArpDispatchTrap + call ArDispatchTrap /* Test previous mode and swapgs if needed */ testb $1, TrapPreviousMode(%rbp) @@ -176,6 +176,6 @@ KernelModeReturn$\Vector: /* Populate common trap handlers */ .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F - ArpCreateTrapHandler 0x\i\j + ArCreateTrapHandler 0x\i\j .endr .endr diff --git a/xtoskrnl/ar/amd64/cpufunc.c b/xtoskrnl/ar/amd64/cpufunc.cc similarity index 83% rename from xtoskrnl/ar/amd64/cpufunc.c rename to xtoskrnl/ar/amd64/cpufunc.cc index d129717..99ee177 100644 --- a/xtoskrnl/ar/amd64/cpufunc.c +++ b/xtoskrnl/ar/amd64/cpufunc.cc @@ -1,15 +1,19 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/cpufunc.c + * FILE: xtoskrnl/ar/amd64/cpufunc.cc * DESCRIPTION: Routines to provide access to special AMD64 CPU instructions * DEVELOPERS: Rafal Kupiec */ -#include +#include -/** +/* Architecture-specific Library */ +namespace AR +{ + + /** * Instructs the processor to clear the interrupt flag. * * @return This routine does not return any value. @@ -18,7 +22,7 @@ */ XTCDECL VOID -ArClearInterruptFlag(VOID) +CpuFunc::ClearInterruptFlag(VOID) { __asm__ volatile("cli"); } @@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID) */ XTCDECL BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers) +CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) { UINT32 MaxLeaf; @@ -76,10 +80,10 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers) */ XTCDECL VOID -ArFlushTlb(VOID) +CpuFunc::FlushTlb(VOID) { /* Flush the TLB by resetting the CR3 */ - ArWriteControlRegister(3, ArReadControlRegister(3)); + WriteControlRegister(3, ReadControlRegister(3)); } /** @@ -91,7 +95,7 @@ ArFlushTlb(VOID) */ XTCDECL ULONG -ArGetCpuFlags(VOID) +CpuFunc::GetCpuFlags(VOID) { ULONG_PTR Flags; @@ -116,7 +120,7 @@ ArGetCpuFlags(VOID) XTASSEMBLY XTCDECL ULONG_PTR -ArGetStackPointer(VOID) +CpuFunc::GetStackPointer(VOID) { /* Get current stack pointer */ __asm__ volatile("movq %%rsp, %%rax\n" @@ -135,7 +139,7 @@ ArGetStackPointer(VOID) */ XTCDECL VOID -ArHalt(VOID) +CpuFunc::Halt(VOID) { __asm__ volatile("hlt"); } @@ -149,12 +153,12 @@ ArHalt(VOID) */ XTCDECL BOOLEAN -ArInterruptsEnabled(VOID) +CpuFunc::InterruptsEnabled(VOID) { ULONG_PTR Flags; /* Get RFLAGS register */ - Flags = ArGetCpuFlags(); + Flags = GetCpuFlags(); /* Check if interrupts are enabled and return result */ return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; @@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID) */ XTCDECL VOID -ArInvalidateTlbEntry(IN PVOID Address) +CpuFunc::InvalidateTlbEntry(IN PVOID Address) { __asm__ volatile("invlpg (%0)" : @@ -192,7 +196,7 @@ ArInvalidateTlbEntry(IN PVOID Address) */ XTCDECL VOID -ArLoadGlobalDescriptorTable(IN PVOID Source) +CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) { __asm__ volatile("lgdt %0" : @@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadInterruptDescriptorTable(IN PVOID Source) +CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) { __asm__ volatile("lidt %0" : @@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadLocalDescriptorTable(IN USHORT Source) +CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) { __asm__ volatile("lldtw %0" : @@ -251,7 +255,7 @@ ArLoadLocalDescriptorTable(IN USHORT Source) */ XTCDECL VOID -ArLoadMxcsrRegister(IN ULONG Source) +CpuFunc::LoadMxcsrRegister(IN ULONG Source) { __asm__ volatile("ldmxcsr %0" : @@ -273,8 +277,8 @@ ArLoadMxcsrRegister(IN ULONG Source) */ XTCDECL VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source) +CpuFunc::LoadSegment(IN USHORT Segment, + IN ULONG Source) { switch(Segment) { @@ -335,7 +339,7 @@ ArLoadSegment(IN USHORT Segment, */ XTCDECL VOID -ArLoadTaskRegister(USHORT Source) +CpuFunc::LoadTaskRegister(USHORT Source) { __asm__ volatile("ltr %0" : @@ -351,7 +355,7 @@ ArLoadTaskRegister(USHORT Source) */ XTCDECL VOID -ArMemoryBarrier(VOID) +CpuFunc::MemoryBarrier(VOID) { LONG Barrier; __asm__ volatile("lock; orl $0, %0;" @@ -371,7 +375,7 @@ ArMemoryBarrier(VOID) */ XTCDECL ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister) +CpuFunc::ReadControlRegister(IN USHORT ControlRegister) { ULONG_PTR Value; @@ -435,7 +439,7 @@ ArReadControlRegister(IN USHORT ControlRegister) */ XTCDECL ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister) +CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) { ULONG_PTR Value; @@ -504,7 +508,7 @@ ArReadDebugRegister(IN USHORT DebugRegister) */ XTCDECL ULONGLONG -ArReadGSQuadWord(ULONG Offset) +CpuFunc::ReadGSQuadWord(ULONG Offset) { ULONGLONG Value; @@ -527,7 +531,7 @@ ArReadGSQuadWord(ULONG Offset) */ XTCDECL ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register) +CpuFunc::ReadModelSpecificRegister(IN ULONG Register) { ULONG Low, High; @@ -548,7 +552,7 @@ ArReadModelSpecificRegister(IN ULONG Register) */ XTCDECL UINT -ArReadMxCsrRegister(VOID) +CpuFunc::ReadMxCsrRegister(VOID) { return __builtin_ia32_stmxcsr(); } @@ -562,7 +566,7 @@ ArReadMxCsrRegister(VOID) */ XTCDECL ULONGLONG -ArReadTimeStampCounter(VOID) +CpuFunc::ReadTimeStampCounter(VOID) { ULONGLONG Low, High; @@ -582,7 +586,7 @@ ArReadTimeStampCounter(VOID) */ XTCDECL VOID -ArReadWriteBarrier(VOID) +CpuFunc::ReadWriteBarrier(VOID) { __asm__ volatile("" : @@ -599,7 +603,7 @@ ArReadWriteBarrier(VOID) */ XTCDECL VOID -ArSetInterruptFlag(VOID) +CpuFunc::SetInterruptFlag(VOID) { __asm__ volatile("sti"); } @@ -616,7 +620,7 @@ ArSetInterruptFlag(VOID) */ XTCDECL VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sgdt %0" : "=m" (*(PSHORT)Destination) @@ -636,7 +640,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sidt %0" : "=m" (*(PSHORT)Destination) @@ -656,7 +660,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sldt %0" : "=m" (*(PSHORT)Destination) @@ -679,8 +683,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination) +CpuFunc::StoreSegment(IN USHORT Segment, + OUT PVOID Destination) { switch(Segment) { @@ -726,7 +730,7 @@ ArStoreSegment(IN USHORT Segment, */ XTCDECL VOID -ArStoreTaskRegister(OUT PVOID Destination) +CpuFunc::StoreTaskRegister(OUT PVOID Destination) { __asm__ volatile("str %0" : "=m" (*(PULONG)Destination) @@ -749,8 +753,8 @@ ArStoreTaskRegister(OUT PVOID Destination) */ XTCDECL VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value) +CpuFunc::WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) { /* Write a value into specified control register */ switch(ControlRegister) @@ -808,8 +812,8 @@ ArWriteControlRegister(IN USHORT ControlRegister, */ XTCDECL VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value) +CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value) { /* Write a value into specified debug register */ switch(DebugRegister) @@ -820,48 +824,56 @@ ArWriteDebugRegister(IN USHORT DebugRegister, : : "r" (Value) : "memory"); + break; case 1: /* Write value to DR1 */ __asm__ volatile("mov %0, %%dr1" : : "r" (Value) : "memory"); + break; case 2: /* Write value to DR2 */ __asm__ volatile("mov %0, %%dr2" : : "r" (Value) : "memory"); + break; case 3: /* Write value to DR3 */ __asm__ volatile("mov %0, %%dr3" : : "r" (Value) : "memory"); + break; case 4: /* Write value to DR4 */ __asm__ volatile("mov %0, %%dr4" : : "r" (Value) : "memory"); + break; case 5: /* Write value to DR5 */ __asm__ volatile("mov %0, %%dr5" : : "r" (Value) : "memory"); + break; case 6: /* Write value to DR6 */ __asm__ volatile("mov %0, %%dr6" : : "r" (Value) : "memory"); + break; case 7: /* Write value to DR7 */ __asm__ volatile("mov %0, %%dr7" : : "r" (Value) : "memory"); + break; } } @@ -877,7 +889,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister, */ XTCDECL VOID -ArWriteEflagsRegister(IN UINT_PTR Value) +CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) { __asm__ volatile("push %0\n" "popf" @@ -900,8 +912,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value) */ XTCDECL VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value) +CpuFunc::WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) { ULONG Low = Value & 0xFFFFFFFF; ULONG High = Value >> 32; @@ -922,10 +934,187 @@ ArWriteModelSpecificRegister(IN ULONG Register, */ XTCDECL VOID -ArYieldProcessor(VOID) +CpuFunc::YieldProcessor(VOID) { __asm__ volatile("pause" : : : "memory"); } + +} /* namespace */ + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArClearInterruptFlag(VOID) +{ + AR::CpuFunc::ClearInterruptFlag(); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +BOOLEAN +ArCpuId(IN OUT PCPUID_REGISTERS Registers) +{ + return AR::CpuFunc::CpuId(Registers); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArHalt(VOID) +{ + AR::CpuFunc::Halt(); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +ULONG_PTR +ArReadControlRegister(IN USHORT ControlRegister) +{ + return AR::CpuFunc::ReadControlRegister(ControlRegister); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +ULONGLONG +ArReadModelSpecificRegister(IN ULONG Register) +{ + return AR::CpuFunc::ReadModelSpecificRegister(Register); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArWriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) +{ + AR::CpuFunc::WriteControlRegister(ControlRegister, Value); +} + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArYieldProcessor(VOID) +{ + AR::CpuFunc::YieldProcessor(); +} + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArReadWriteBarrier(VOID) +{ + AR::CpuFunc::ReadWriteBarrier(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +BOOLEAN +ArInterruptsEnabled(VOID) +{ + return AR::CpuFunc::InterruptsEnabled(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArSetInterruptFlag(VOID) +{ + AR::CpuFunc::SetInterruptFlag(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +ULONGLONG +ArReadGSQuadWord(ULONG Offset) +{ + return AR::CpuFunc::ReadGSQuadWord(Offset); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +ULONG_PTR +ArReadDebugRegister(IN USHORT DebugRegister) +{ + return AR::CpuFunc::ReadDebugRegister(DebugRegister); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +UINT +ArReadMxCsrRegister(VOID) +{ + return AR::CpuFunc::ReadMxCsrRegister(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreGlobalDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreGlobalDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreInterruptDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreInterruptDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreLocalDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreLocalDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreTaskRegister(OUT PVOID Destination) +{ + AR::CpuFunc::StoreTaskRegister(Destination); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArFlushTlb(VOID) +{ + AR::CpuFunc::FlushTlb(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArWriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) +{ + AR::CpuFunc::WriteModelSpecificRegister(Register, Value); +} diff --git a/xtoskrnl/ar/amd64/data.cc b/xtoskrnl/ar/amd64/data.cc new file mode 100644 index 0000000..b0712d9 --- /dev/null +++ b/xtoskrnl/ar/amd64/data.cc @@ -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 + */ + +#include + + +/* 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 */ diff --git a/xtoskrnl/ar/amd64/globals.c b/xtoskrnl/ar/amd64/globals.c deleted file mode 100644 index 2221171..0000000 --- a/xtoskrnl/ar/amd64/globals.c +++ /dev/null @@ -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 - */ - -#include - - -/* 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}; diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.cc similarity index 54% rename from xtoskrnl/ar/amd64/procsup.c rename to xtoskrnl/ar/amd64/procsup.cc index d58a889..3bbef12 100644 --- a/xtoskrnl/ar/amd64/procsup.c +++ b/xtoskrnl/ar/amd64/procsup.cc @@ -1,121 +1,28 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/procsup.c + * FILE: xtoskrnl/ar/amd64/procsup.cc * DESCRIPTION: AMD64 processor functionality support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Architecture-specific Library */ +namespace AR +{ + /** - * Initializes AMD64 processor specific structures. + * Gets the base address of the kernel boot stack. * - * @return This routine does not return any value. + * @return This routine returns a pointer to the kernel boot stack. * * @since XT 1.0 */ -XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures) +PVOID ProcSup::GetBootStack(VOID) { - KDESCRIPTOR GdtDescriptor, IdtDescriptor; - PVOID KernelBootStack, KernelFaultStack; - PKPROCESSOR_BLOCK ProcessorBlock; - PKGDTENTRY Gdt; - PKIDTENTRY Idt; - PKTSS Tss; - - /* Check if processor structures buffer provided */ - if(ProcessorStructures) - { - /* Assign CPU structures from provided buffer */ - ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, - &KernelBootStack, &KernelFaultStack); - - /* Use global IDT */ - Idt = ArInitialIdt; - } - else - { - /* Use initial structures */ - Gdt = ArInitialGdt; - Idt = ArInitialIdt; - Tss = &ArInitialTss; - KernelBootStack = &ArKernelBootStack; - KernelFaultStack = &ArKernelFaultStack; - ProcessorBlock = &ArInitialProcessorBlock; - } - - /* Initialize processor block */ - ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); - - /* Initialize GDT, IDT and TSS */ - ArpInitializeGdt(ProcessorBlock); - ArpInitializeIdt(ProcessorBlock); - ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); - - /* Set GDT and IDT descriptors */ - GdtDescriptor.Base = Gdt; - GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; - IdtDescriptor.Base = Idt; - IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; - - /* Load GDT, IDT and TSS */ - ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); - ArLoadTaskRegister((UINT)KGDT_SYS_TSS); - - /* Enter passive IRQ level */ - HlSetRunLevel(PASSIVE_LEVEL); - - /* Initialize segment registers */ - ArpInitializeSegments(); - - /* Set GS base */ - ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); - ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); - - /* Initialize processor registers */ - ArpInitializeProcessorRegisters(); - - /* Identify processor */ - ArpIdentifyProcessor(); -} - -/** - * Updates an existing AMD64 GDT entry with new base address. - * - * @param Gdt - * Supplies a pointer to the GDT. - * - * @param Selector - * Specifies a segment selector of the GDT entry. - * - * @param Base - * Specifies a base address value of the descriptor. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base) -{ - PKGDTENTRY GdtEntry; - - /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); - - /* Set new GDT descriptor base */ - GdtEntry->BaseLow = (Base & 0xFFFF); - GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); - GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); - GdtEntry->BaseUpper = (Base >> 32); + return (PVOID)BootStack; } /** @@ -128,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpIdentifyProcessor(VOID) +ProcSup::IdentifyProcessor(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; @@ -143,10 +50,10 @@ ArpIdentifyProcessor(VOID) /* Get CPU vendor by issueing CPUID instruction */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; + Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; @@ -155,7 +62,7 @@ ArpIdentifyProcessor(VOID) /* Get CPU standard features */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; - ArCpuId(&CpuRegisters); + CpuFunc::CpuId(&CpuRegisters); /* Store CPU signature in processor control block */ CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; @@ -195,6 +102,81 @@ ArpIdentifyProcessor(VOID) /* TODO: Store a list of CPU features in processor control block */ } +/** + * Initializes AMD64 processor specific structures. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) +{ + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PVOID KernelBootStack, KernelFaultStack; + PKPROCESSOR_BLOCK ProcessorBlock; + PKGDTENTRY Gdt; + PKIDTENTRY Idt; + PKTSS Tss; + + /* Check if processor structures buffer provided */ + if(ProcessorStructures) + { + /* Assign CPU structures from provided buffer */ + InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, + &KernelBootStack, &KernelFaultStack); + + /* Use global IDT */ + Idt = InitialIdt; + } + else + { + /* Use initial structures */ + Gdt = InitialGdt; + Idt = InitialIdt; + Tss = &InitialTss; + KernelBootStack = &BootStack; + KernelFaultStack = &FaultStack; + ProcessorBlock = &InitialProcessorBlock; + } + + /* Initialize processor block */ + InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); + + /* Initialize GDT, IDT and TSS */ + InitializeGdt(ProcessorBlock); + InitializeIdt(ProcessorBlock); + InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); + + /* Set GDT and IDT descriptors */ + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; + + /* Load GDT, IDT and TSS */ + CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); + CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); + CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Enter passive IRQ level */ + HlSetRunLevel(PASSIVE_LEVEL); + + /* Initialize segment registers */ + InitializeSegments(); + + /* Set GS base */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); + CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); + + /* Initialize processor registers */ + InitializeProcessorRegisters(); + + /* Identify processor */ + IdentifyProcessor(); +} + /** * Initializes the kernel's Global Descriptor Table (GDT). * @@ -207,19 +189,21 @@ ArpIdentifyProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* Initialize GDT entries */ - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 1); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, + sizeof(KTSS) - 1, AMD64_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, + (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); } /** @@ -234,7 +218,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { UINT Vector; @@ -242,34 +226,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) for(Vector = 0; Vector < IDT_ENTRIES; Vector++) { /* Set the IDT to handle unexpected interrupts */ - ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); } /* Setup IDT handlers for known interrupts and traps */ - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x1F, ArpTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2F, ArpTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0xE1, ArpTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); } /** @@ -293,18 +277,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack) +ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) { /* Set processor block and processor control block */ ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; /* Set GDT, IDT and TSS descriptors */ - ProcessorBlock->GdtBase = (PVOID)Gdt; + ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt; ProcessorBlock->IdtBase = Idt; ProcessorBlock->TssBase = Tss; ProcessorBlock->Prcb.RspBase = Tss->Rsp0; @@ -325,7 +309,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.NextThread = NULL; + ProcessorBlock->Prcb.NextThread = nullptr; /* Set initial MXCSR register value */ ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR; @@ -343,56 +327,50 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpInitializeProcessorRegisters(VOID) +ProcSup::InitializeProcessorRegisters(VOID) { ULONGLONG PatAttributes; /* Enable FXSAVE restore */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_FXSR); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_FXSR); /* Enable XMMI exceptions */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_XMMEXCPT); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT); /* Set debugger extension */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_DE); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_DE); /* Enable large pages */ - ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PSE); + CpuFunc::WriteControlRegister(4, CpuFunc::ReadControlRegister(4) | CR4_PSE); /* Enable write-protection */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP); /* Set alignment mask */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_AM); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_AM); /* Disable FPU monitoring */ - ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_MP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_MP); /* Disable x87 FPU exceptions */ - ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_NE); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) & ~CR0_NE); /* Flush the TLB */ - ArFlushTlb(); - - /* Initialize system calls MSR */ - ArWriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); - ArWriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&ArpHandleSystemCall32); - ArWriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&ArpHandleSystemCall64); - ArWriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK); - - /* Enable system call extensions (SCE) in EFER MSR */ - ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE); + CpuFunc::FlushTlb(); + /* Initialize system call MSRs */ + Traps::InitializeSystemCallMsrs(); + /* Enable No-Execute (NXE) in EFER MSR */ - ArWriteModelSpecificRegister(X86_MSR_EFER, ArReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); + CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE); /* Initialize Page Attribute Table */ PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56); - ArWriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); + CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); /* Initialize MXCSR register */ - ArLoadMxcsrRegister(INITIAL_MXCSR); + CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR); } /** @@ -422,12 +400,12 @@ ArpInitializeProcessorRegisters(VOID) */ XTAPI VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack) +ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack) { UINT_PTR Address; @@ -442,15 +420,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, *KernelFaultStack = (PVOID)Address; /* Assign a space for GDT and advance */ - *Gdt = (PVOID)Address; - Address += sizeof(ArInitialGdt); + *Gdt = (PKGDTENTRY)(PVOID)Address; + Address += sizeof(InitialGdt); /* Assign a space for Processor Block and advance */ - *ProcessorBlock = (PVOID)Address; - Address += sizeof(ArInitialProcessorBlock); + *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; + Address += sizeof(InitialProcessorBlock); /* Assign a space for TSS */ - *Tss = (PVOID)Address; + *Tss = (PKTSS)(PVOID)Address; } /** @@ -462,15 +440,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, */ XTAPI VOID -ArpInitializeSegments(VOID) +ProcSup::InitializeSegments(VOID) { /* Initialize segments */ - ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); - ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); - ArLoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_SS, KGDT_R0_DATA); + CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); + CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA); } /** @@ -488,9 +466,9 @@ ArpInitializeSegments(VOID) */ XTAPI VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack) +ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack) { /* Fill TSS with zeroes */ RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); @@ -532,13 +510,13 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode) +ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) { PKGDTENTRY GdtEntry; UCHAR Granularity; @@ -580,6 +558,40 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->MustBeZero = 0; } +/** + * Updates an existing AMD64 GDT entry with new base address. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base) +{ + PKGDTENTRY GdtEntry; + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); + + /* Set new GDT descriptor base */ + GdtEntry->BaseLow = (Base & 0xFFFF); + GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); + GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); + GdtEntry->BaseUpper = (Base >> 32); +} + /** * Fills in a call, interrupt, task or trap gate entry. * @@ -607,12 +619,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access) +ProcSup::SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) { /* Setup the gate */ Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); @@ -624,3 +636,68 @@ ArpSetIdtGate(IN PKIDTENTRY Idt, Idt[Vector].Selector = Selector; Idt[Vector].Type = 0xE; } + +/** + * Switches execution to a new boot stack and transfers control to the specified routine + * + * @param TargetRoutine + * Supplies the address of the routine to transfer control to after switching to the new boot stack. + * + * @param ReservedStackSize + * Specifies the amount of stack space to reserve below the new stack pointer. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ProcSup::SwitchBootStack(PVOID TargetRoutine, + ULONG_PTR ReservedStackSize) +{ + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + ULONG_PTR Stack = ((ULONG_PTR)&BootStack + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + + /* Discard old stack frame, switch stack, reserve space, and jump to the target routine */ + __asm__ volatile("mov %0, %%rax\n" + "xor %%rbp, %%rbp\n" + "mov %%rax, %%rsp\n" + "sub %1, %%rsp\n" + "jmp *%2\n" + : + : "m" (Stack), + "r" (ReservedStackSize), + "r" (TargetRoutine) + : "rax", "rbp", "rsp", "memory"); +} + +} /* 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); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +ArSwitchBootStack(IN PVOID TargetRoutine, + IN ULONG_PTR ReservedStackSize) +{ + AR::ProcSup::SwitchBootStack(TargetRoutine, ReservedStackSize); +} diff --git a/xtoskrnl/ar/amd64/traps.c b/xtoskrnl/ar/amd64/traps.cc similarity index 75% rename from xtoskrnl/ar/amd64/traps.c rename to xtoskrnl/ar/amd64/traps.cc index 66540f0..b9ca2fc 100644 --- a/xtoskrnl/ar/amd64/traps.c +++ b/xtoskrnl/ar/amd64/traps.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/amd64/traps.c + * FILE: xtoskrnl/ar/amd64/traps.cc * DESCRIPTION: AMD64 system traps * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Architecture-specific Library */ +namespace AR +{ + /** * Dispatches the trap provided by common trap handler. * @@ -21,124 +25,138 @@ */ XTCDECL VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) +Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame) { /* Check vector and call appropriate handler */ switch(TrapFrame->Vector) { case 0x00: /* Divide By Zero exception */ - ArpHandleTrap00(TrapFrame); + HandleTrap00(TrapFrame); break; case 0x01: /* Debug exception */ - ArpHandleTrap01(TrapFrame); + HandleTrap01(TrapFrame); break; case 0x02: /* Non-Maskable Interrupt (NMI) */ - ArpHandleTrap02(TrapFrame); + HandleTrap02(TrapFrame); break; case 0x03: /* INT3 instruction executed */ - ArpHandleTrap03(TrapFrame); + HandleTrap03(TrapFrame); break; case 0x04: /* Overflow exception */ - ArpHandleTrap04(TrapFrame); + HandleTrap04(TrapFrame); break; case 0x05: /* Bound Range Exceeded exception */ - ArpHandleTrap05(TrapFrame); + HandleTrap05(TrapFrame); break; case 0x06: /* Invalid Opcode exception */ - ArpHandleTrap06(TrapFrame); + HandleTrap06(TrapFrame); break; case 0x07: /* Device Not Available exception */ - ArpHandleTrap07(TrapFrame); + HandleTrap07(TrapFrame); break; case 0x08: /* Double Fault exception */ - ArpHandleTrap08(TrapFrame); + HandleTrap08(TrapFrame); break; case 0x09: /* Segment Overrun exception */ - ArpHandleTrap09(TrapFrame); + HandleTrap09(TrapFrame); break; case 0x0A: /* Invalid TSS exception */ - ArpHandleTrap0A(TrapFrame); + HandleTrap0A(TrapFrame); break; case 0x0B: /* Segment Not Present exception */ - ArpHandleTrap0B(TrapFrame); + HandleTrap0B(TrapFrame); break; case 0x0C: /* Stack Segment Fault exception */ - ArpHandleTrap0C(TrapFrame); + HandleTrap0C(TrapFrame); break; case 0x0D: /* General Protection Fault (GPF) exception*/ - ArpHandleTrap0D(TrapFrame); + HandleTrap0D(TrapFrame); break; case 0x0E: /* Page Fault exception */ - ArpHandleTrap0E(TrapFrame); + HandleTrap0E(TrapFrame); break; case 0x10: /* X87 Floating-Point exception */ - ArpHandleTrap10(TrapFrame); + HandleTrap10(TrapFrame); break; case 0x11: /* Alignment Check exception */ - ArpHandleTrap11(TrapFrame); + HandleTrap11(TrapFrame); break; case 0x12: /* Machine Check exception */ - ArpHandleTrap12(TrapFrame); + HandleTrap12(TrapFrame); break; case 0x13: /* SIMD Floating-Point exception */ - ArpHandleTrap13(TrapFrame); + HandleTrap13(TrapFrame); break; case 0x1F: /* Software Interrupt at APC level */ - ArpHandleTrap1F(TrapFrame); + HandleTrap1F(TrapFrame); break; case 0x2C: /* Assertion raised */ - ArpHandleTrap2C(TrapFrame); + HandleTrap2C(TrapFrame); break; case 0x2D: /* Debug-Service-Request raised */ - ArpHandleTrap2D(TrapFrame); + HandleTrap2D(TrapFrame); break; case 0x2F: /* Software Interrupt at DISPATCH level */ - ArpHandleTrap2F(TrapFrame); + HandleTrap2F(TrapFrame); break; case 0xE1: /* InterProcessor Interrupt (IPI) */ - ArpHandleTrapE1(TrapFrame); + HandleTrapE1(TrapFrame); break; default: /* Unknown/Unexpected trap */ - ArpHandleTrapFF(TrapFrame); + HandleTrapFF(TrapFrame); break; } } +/** + * Handles a 32-bit system call. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -ArpHandleSystemCall32(VOID) +Traps::HandleSystemCall32(VOID) { DebugPrint(L"Handled 32-bit system call!\n"); } +/** + * Handles a 64-bit system call. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ XTCDECL VOID -ArpHandleSystemCall64(VOID) +Traps::HandleSystemCall64(VOID) { DebugPrint(L"Handled 64-bit system call!\n"); } @@ -155,7 +173,7 @@ ArpHandleSystemCall64(VOID) */ XTCDECL VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); for(;;); @@ -173,7 +191,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug exception (0x01)!\n"); for(;;); @@ -191,7 +209,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); for(;;); @@ -209,7 +227,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled INT3 (0x03)!\n"); for(;;); @@ -227,7 +245,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Overflow exception (0x04)!\n"); for(;;); @@ -245,7 +263,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); for(;;); @@ -263,7 +281,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); for(;;); @@ -281,7 +299,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); for(;;); @@ -299,7 +317,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); for(;;); @@ -317,7 +335,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); for(;;); @@ -335,7 +353,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); for(;;); @@ -353,7 +371,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); for(;;); @@ -371,7 +389,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); for(;;); @@ -389,7 +407,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); for(;;); @@ -407,7 +425,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); for(;;); @@ -425,7 +443,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); for(;;); @@ -443,7 +461,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); for(;;); @@ -461,7 +479,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); for(;;); @@ -479,7 +497,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); for(;;); @@ -497,7 +515,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap1F(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled software interrupt at APC level (0x1F)!\n"); } @@ -514,7 +532,7 @@ ArpHandleTrap1F(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Assertion (0x2C)!\n"); for(;;); @@ -532,7 +550,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); for(;;); @@ -550,7 +568,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2F(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled software interrupt at DISPATCH level (0x2F)!\n"); } @@ -567,7 +585,7 @@ ArpHandleTrap2F(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrapE1(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled IPI interrupt (0xE1)!\n"); } @@ -584,8 +602,49 @@ ArpHandleTrapE1(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); for(;;); } + +/** + * Initializes system call MSRs. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +Traps::InitializeSystemCallMsrs(VOID) +{ + /* Initialize system calls MSR */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); + CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32); + CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64); + CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK); + + /* Enable system call extensions (SCE) in EFER MSR */ + CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE); +} + +} /* namespace */ + +/** + * C-linkage wrapper for dispatching the trap provided by common trap handler. + * + * @param TrapFrame + * Supplies a kernel trap frame pushed by common trap handler on the stack. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +ArDispatchTrap(IN PKTRAP_FRAME TrapFrame) +{ + AR::Traps::DispatchTrap(TrapFrame); +} diff --git a/xtoskrnl/ar/i686/archsup.S b/xtoskrnl/ar/i686/archsup.S index e80ac42..d9e465d 100644 --- a/xtoskrnl/ar/i686/archsup.S +++ b/xtoskrnl/ar/i686/archsup.S @@ -22,9 +22,9 @@ * * @since XT 1.0 */ -.macro ArpCreateTrapHandler Vector -.global _ArpTrap\Vector -_ArpTrap\Vector: +.macro ArCreateTrapHandler Vector +.global _ArTrap\Vector +_ArTrap\Vector: /* Push fake error code for non-error vectors */ .if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30 push $0 @@ -84,7 +84,7 @@ KernelMode$\Vector: /* Push Frame Pointer, clear direction flag and pass to trap dispatcher */ push %esp cld - call _ArpDispatchTrap + call _ArDispatchTrap /* Clean up the stack */ add $4, %esp @@ -121,6 +121,6 @@ KernelModeReturn$\Vector: /* Populate common trap handlers */ .irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F .irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F - ArpCreateTrapHandler 0x\i\j + ArCreateTrapHandler 0x\i\j .endr .endr diff --git a/xtoskrnl/ar/i686/cpufunc.c b/xtoskrnl/ar/i686/cpufunc.cc similarity index 83% rename from xtoskrnl/ar/i686/cpufunc.c rename to xtoskrnl/ar/i686/cpufunc.cc index 27b6676..0c7eca5 100644 --- a/xtoskrnl/ar/i686/cpufunc.c +++ b/xtoskrnl/ar/i686/cpufunc.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/cpufunc.c + * FILE: xtoskrnl/ar/i686/cpufunc.cc * DESCRIPTION: Routines to provide access to special i686 CPU instructions * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Architecture-specific Library */ +namespace AR +{ + /** * Instructs the processor to clear the interrupt flag. * @@ -18,7 +22,7 @@ */ XTCDECL VOID -ArClearInterruptFlag(VOID) +CpuFunc::ClearInterruptFlag(VOID) { __asm__ volatile("cli"); } @@ -35,7 +39,7 @@ ArClearInterruptFlag(VOID) */ XTCDECL BOOLEAN -ArCpuId(IN OUT PCPUID_REGISTERS Registers) +CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) { UINT32 MaxLeaf; @@ -76,7 +80,7 @@ ArCpuId(IN OUT PCPUID_REGISTERS Registers) */ XTCDECL VOID -ArFlushTlb(VOID) +CpuFunc::FlushTlb(VOID) { /* Flush the TLB by resetting the CR3 */ ArWriteControlRegister(3, ArReadControlRegister(3)); @@ -91,7 +95,7 @@ ArFlushTlb(VOID) */ XTCDECL ULONG -ArGetCpuFlags(VOID) +CpuFunc::GetCpuFlags(VOID) { ULONG_PTR Flags; @@ -116,7 +120,7 @@ ArGetCpuFlags(VOID) XTASSEMBLY XTCDECL ULONG_PTR -ArGetStackPointer(VOID) +CpuFunc::GetStackPointer(VOID) { /* Get current stack pointer */ __asm__ volatile("mov %%esp, %%eax\n" @@ -135,7 +139,7 @@ ArGetStackPointer(VOID) */ XTCDECL VOID -ArHalt(VOID) +CpuFunc::Halt(VOID) { __asm__ volatile("hlt"); } @@ -149,12 +153,12 @@ ArHalt(VOID) */ XTCDECL BOOLEAN -ArInterruptsEnabled(VOID) +CpuFunc::InterruptsEnabled(VOID) { ULONG_PTR Flags; /* Get RFLAGS register */ - Flags = ArGetCpuFlags(); + Flags = GetCpuFlags(); /* Check if interrupts are enabled and return result */ return (Flags & X86_EFLAGS_IF_MASK) ? TRUE : FALSE; @@ -172,7 +176,7 @@ ArInterruptsEnabled(VOID) */ XTCDECL VOID -ArInvalidateTlbEntry(PVOID Address) +CpuFunc::InvalidateTlbEntry(PVOID Address) { __asm__ volatile("invlpg (%0)" : @@ -192,7 +196,7 @@ ArInvalidateTlbEntry(PVOID Address) */ XTCDECL VOID -ArLoadGlobalDescriptorTable(IN PVOID Source) +CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) { __asm__ volatile("lgdt %0" : @@ -212,7 +216,7 @@ ArLoadGlobalDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadInterruptDescriptorTable(IN PVOID Source) +CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) { __asm__ volatile("lidt %0" : @@ -232,7 +236,7 @@ ArLoadInterruptDescriptorTable(IN PVOID Source) */ XTCDECL VOID -ArLoadLocalDescriptorTable(IN USHORT Source) +CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) { __asm__ volatile("lldtw %0" : @@ -254,8 +258,8 @@ ArLoadLocalDescriptorTable(IN USHORT Source) */ XTCDECL VOID -ArLoadSegment(IN USHORT Segment, - IN ULONG Source) +CpuFunc::LoadSegment(IN USHORT Segment, + IN ULONG Source) { switch(Segment) { @@ -316,7 +320,7 @@ ArLoadSegment(IN USHORT Segment, */ XTCDECL VOID -ArLoadTaskRegister(USHORT Source) +CpuFunc::LoadTaskRegister(USHORT Source) { __asm__ volatile("ltr %0" : @@ -332,7 +336,7 @@ ArLoadTaskRegister(USHORT Source) */ XTCDECL VOID -ArMemoryBarrier(VOID) +CpuFunc::MemoryBarrier(VOID) { LONG Barrier; __asm__ volatile("xchg %%eax, %0" @@ -353,7 +357,7 @@ ArMemoryBarrier(VOID) */ XTCDECL ULONG_PTR -ArReadControlRegister(IN USHORT ControlRegister) +CpuFunc::ReadControlRegister(IN USHORT ControlRegister) { ULONG_PTR Value; @@ -410,7 +414,7 @@ ArReadControlRegister(IN USHORT ControlRegister) */ XTCDECL ULONG_PTR -ArReadDebugRegister(IN USHORT DebugRegister) +CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) { ULONG_PTR Value; @@ -479,7 +483,7 @@ ArReadDebugRegister(IN USHORT DebugRegister) */ XTCDECL ULONG -ArReadFSDualWord(ULONG Offset) +CpuFunc::ReadFSDualWord(ULONG Offset) { ULONG Value; __asm__ volatile("movl %%fs:%a[Offset], %k[Value]" @@ -500,7 +504,7 @@ ArReadFSDualWord(ULONG Offset) */ XTCDECL ULONGLONG -ArReadModelSpecificRegister(IN ULONG Register) +CpuFunc::ReadModelSpecificRegister(IN ULONG Register) { ULONGLONG Value; @@ -519,7 +523,7 @@ ArReadModelSpecificRegister(IN ULONG Register) */ XTCDECL UINT -ArReadMxCsrRegister(VOID) +CpuFunc::ReadMxCsrRegister(VOID) { return __builtin_ia32_stmxcsr(); } @@ -533,7 +537,7 @@ ArReadMxCsrRegister(VOID) */ XTCDECL ULONGLONG -ArReadTimeStampCounter(VOID) +CpuFunc::ReadTimeStampCounter(VOID) { ULONGLONG Value; @@ -552,7 +556,7 @@ ArReadTimeStampCounter(VOID) */ XTCDECL VOID -ArReadWriteBarrier(VOID) +CpuFunc::ReadWriteBarrier(VOID) { __asm__ volatile("" : @@ -569,7 +573,7 @@ ArReadWriteBarrier(VOID) */ XTCDECL VOID -ArSetInterruptFlag(VOID) +CpuFunc::SetInterruptFlag(VOID) { __asm__ volatile("sti"); } @@ -586,7 +590,7 @@ ArSetInterruptFlag(VOID) */ XTCDECL VOID -ArStoreGlobalDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sgdt %0" : "=m" (*(PSHORT)Destination) @@ -606,7 +610,7 @@ ArStoreGlobalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreInterruptDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sidt %0" : "=m" (*(PSHORT)Destination) @@ -626,7 +630,7 @@ ArStoreInterruptDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreLocalDescriptorTable(OUT PVOID Destination) +CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) { __asm__ volatile("sldt %0" : "=m" (*(PSHORT)Destination) @@ -649,8 +653,8 @@ ArStoreLocalDescriptorTable(OUT PVOID Destination) */ XTCDECL VOID -ArStoreSegment(IN USHORT Segment, - OUT PVOID Destination) +CpuFunc::StoreSegment(IN USHORT Segment, + OUT PVOID Destination) { switch(Segment) { @@ -696,7 +700,7 @@ ArStoreSegment(IN USHORT Segment, */ XTCDECL VOID -ArStoreTaskRegister(OUT PVOID Destination) +CpuFunc::StoreTaskRegister(OUT PVOID Destination) { __asm__ volatile("str %0" : "=m" (*(PULONG)Destination) @@ -719,8 +723,8 @@ ArStoreTaskRegister(OUT PVOID Destination) */ XTCDECL VOID -ArWriteControlRegister(IN USHORT ControlRegister, - IN UINT_PTR Value) +CpuFunc::WriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) { /* Write a value into specified control register */ switch(ControlRegister) @@ -771,8 +775,8 @@ ArWriteControlRegister(IN USHORT ControlRegister, */ XTCDECL VOID -ArWriteDebugRegister(IN USHORT DebugRegister, - IN UINT_PTR Value) +CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, + IN UINT_PTR Value) { /* Write a value into specified debug register */ switch(DebugRegister) @@ -840,7 +844,7 @@ ArWriteDebugRegister(IN USHORT DebugRegister, */ XTCDECL VOID -ArWriteEflagsRegister(IN UINT_PTR Value) +CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) { __asm__ volatile("push %0\n" "popf" @@ -863,8 +867,8 @@ ArWriteEflagsRegister(IN UINT_PTR Value) */ XTCDECL VOID -ArWriteModelSpecificRegister(IN ULONG Register, - IN ULONGLONG Value) +CpuFunc::WriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) { __asm__ volatile("wrmsr" : @@ -881,10 +885,185 @@ ArWriteModelSpecificRegister(IN ULONG Register, */ XTCDECL VOID -ArYieldProcessor(VOID) +CpuFunc::YieldProcessor(VOID) { __asm__ volatile("pause" : : : "memory"); } + +} /* namespace */ + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArClearInterruptFlag(VOID) +{ + AR::CpuFunc::ClearInterruptFlag(); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +BOOLEAN +ArCpuId(IN OUT PCPUID_REGISTERS Registers) +{ + return AR::CpuFunc::CpuId(Registers); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArHalt(VOID) +{ + AR::CpuFunc::Halt(); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +ULONG_PTR +ArReadControlRegister(IN USHORT ControlRegister) +{ + return AR::CpuFunc::ReadControlRegister(ControlRegister); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +ULONGLONG +ArReadModelSpecificRegister(IN ULONG Register) +{ + return AR::CpuFunc::ReadModelSpecificRegister(Register); +} + +/* NEEDED BY XTLDR */ +XTCLINK +XTCDECL +VOID +ArWriteControlRegister(IN USHORT ControlRegister, + IN UINT_PTR Value) +{ + AR::CpuFunc::WriteControlRegister(ControlRegister, Value); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArYieldProcessor(VOID) +{ + AR::CpuFunc::YieldProcessor(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArReadWriteBarrier(VOID) +{ + AR::CpuFunc::ReadWriteBarrier(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +BOOLEAN +ArInterruptsEnabled(VOID) +{ + return AR::CpuFunc::InterruptsEnabled(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArSetInterruptFlag(VOID) +{ + AR::CpuFunc::SetInterruptFlag(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +ULONG +ArReadFSDualWord(ULONG Offset) +{ + return AR::CpuFunc::ReadFSDualWord(Offset); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +ULONG_PTR +ArReadDebugRegister(IN USHORT DebugRegister) +{ + return AR::CpuFunc::ReadDebugRegister(DebugRegister); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +UINT +ArReadMxCsrRegister(VOID) +{ + return AR::CpuFunc::ReadMxCsrRegister(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreGlobalDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreGlobalDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreInterruptDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreInterruptDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreLocalDescriptorTable(IN PVOID Source) +{ + AR::CpuFunc::StoreLocalDescriptorTable(Source); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArStoreTaskRegister(OUT PVOID Destination) +{ + AR::CpuFunc::StoreTaskRegister(Destination); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArFlushTlb(VOID) +{ + AR::CpuFunc::FlushTlb(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTCDECL +VOID +ArWriteModelSpecificRegister(IN ULONG Register, + IN ULONGLONG Value) +{ + AR::CpuFunc::WriteModelSpecificRegister(Register, Value); +} diff --git a/xtoskrnl/ar/i686/data.cc b/xtoskrnl/ar/i686/data.cc new file mode 100644 index 0000000..110304c --- /dev/null +++ b/xtoskrnl/ar/i686/data.cc @@ -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 + */ + +#include + + +/* 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 */ diff --git a/xtoskrnl/ar/i686/globals.c b/xtoskrnl/ar/i686/globals.c deleted file mode 100644 index af4f87d..0000000 --- a/xtoskrnl/ar/i686/globals.c +++ /dev/null @@ -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 - */ - -#include - - -/* 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}; diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.cc similarity index 62% rename from xtoskrnl/ar/i686/procsup.c rename to xtoskrnl/ar/i686/procsup.cc index 161257b..f88f6bf 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.cc @@ -1,116 +1,28 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/procsup.c + * FILE: xtoskrnl/ar/i686/procsup.cc * DESCRIPTION: I686 processor functionality support * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Architecture-specific Library */ +namespace AR +{ + /** - * Initializes i686 processor specific structures. + * Gets the base address of the kernel boot stack. * - * @return This routine does not return any value. + * @return This routine returns a pointer to the kernel boot stack. * * @since XT 1.0 */ -XTAPI -VOID -ArInitializeProcessor(IN PVOID ProcessorStructures) +PVOID ProcSup::GetBootStack(VOID) { - KDESCRIPTOR GdtDescriptor, IdtDescriptor; - PVOID KernelBootStack, KernelFaultStack; - PKPROCESSOR_BLOCK ProcessorBlock; - PKGDTENTRY Gdt; - PKIDTENTRY Idt; - PKTSS Tss; - - /* Check if processor structures buffer provided */ - if(ProcessorStructures) - { - /* Assign CPU structures from provided buffer */ - ArpInitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, - &KernelBootStack, &KernelFaultStack); - - /* Use global IDT */ - Idt = ArInitialIdt; - } - else - { - /* Use initial structures */ - Gdt = ArInitialGdt; - Idt = ArInitialIdt; - Tss = &ArInitialTss; - KernelBootStack = &ArKernelBootStack; - KernelFaultStack = &ArKernelFaultStack; - ProcessorBlock = &ArInitialProcessorBlock; - } - - /* Initialize processor block */ - ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); - - /* Initialize GDT, IDT and TSS */ - ArpInitializeGdt(ProcessorBlock); - ArpInitializeIdt(ProcessorBlock); - ArpInitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); - - /* Set GDT and IDT descriptors */ - GdtDescriptor.Base = Gdt; - GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; - IdtDescriptor.Base = Idt; - IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; - - /* Load GDT, IDT and TSS */ - ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); - ArLoadTaskRegister((UINT)KGDT_SYS_TSS); - - /* Enter passive IRQ level */ - HlSetRunLevel(PASSIVE_LEVEL); - - /* Initialize segment registers */ - ArpInitializeSegments(); - - /* Initialize processor registers */ - ArpInitializeProcessorRegisters(); - - /* Identify processor */ - ArpIdentifyProcessor(); -} - -/** - * Updates an existing i686 GDT entry with new base address. - * - * @param Gdt - * Supplies a pointer to the GDT. - * - * @param Selector - * Specifies a segment selector of the GDT entry. - * - * @param Base - * Specifies a base address value of the descriptor. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -ArSetGdtEntryBase(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base) -{ - PKGDTENTRY GdtEntry; - - /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); - - /* Set new GDT descriptor base */ - GdtEntry->BaseLow = (Base & 0xFFFF); - GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); - GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); + return (PVOID)BootStack; } /** @@ -123,7 +35,7 @@ ArSetGdtEntryBase(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpIdentifyProcessor(VOID) +ProcSup::IdentifyProcessor(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; @@ -141,7 +53,7 @@ ArpIdentifyProcessor(VOID) ArCpuId(&CpuRegisters); /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; + Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; *(PULONG)&Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; *(PULONG)&Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; @@ -190,6 +102,77 @@ ArpIdentifyProcessor(VOID) /* TODO: Store a list of CPU features in processor control block */ } +/** + * Initializes i686 processor specific structures. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) +{ + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PVOID KernelBootStack, KernelFaultStack; + PKPROCESSOR_BLOCK ProcessorBlock; + PKGDTENTRY Gdt; + PKIDTENTRY Idt; + PKTSS Tss; + + /* Check if processor structures buffer provided */ + if(ProcessorStructures) + { + /* Assign CPU structures from provided buffer */ + InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock, + &KernelBootStack, &KernelFaultStack); + + /* Use global IDT */ + Idt = InitialIdt; + } + else + { + /* Use initial structures */ + Gdt = InitialGdt; + Idt = InitialIdt; + Tss = &InitialTss; + KernelBootStack = &BootStack; + KernelFaultStack = &FaultStack; + ProcessorBlock = &InitialProcessorBlock; + } + + /* Initialize processor block */ + InitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, KernelFaultStack); + + /* Initialize GDT, IDT and TSS */ + InitializeGdt(ProcessorBlock); + InitializeIdt(ProcessorBlock); + InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack); + + /* Set GDT and IDT descriptors */ + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; + + /* Load GDT, IDT and TSS */ + CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); + CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); + CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Enter passive IRQ level */ + HlSetRunLevel(PASSIVE_LEVEL); + + /* Initialize segment registers */ + InitializeSegments(); + + /* Initialize processor registers */ + InitializeProcessorRegisters(); + + /* Identify processor */ + IdentifyProcessor(); +} + /** * Initializes the kernel's Global Descriptor Table (GDT). * @@ -202,23 +185,23 @@ ArpIdentifyProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* Initialize GDT entries */ - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); - ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONG_PTR)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PB, (ULONG_PTR)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + SetGdtEntry(ProcessorBlock->GdtBase, KGDT_ALIAS, (ULONG_PTR)ProcessorBlock->GdtBase, (GDT_ENTRIES * sizeof(KGDTENTRY)) - 1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); } /** @@ -233,7 +216,7 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { UINT Vector; @@ -241,34 +224,34 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) for(Vector = 0; Vector < IDT_ENTRIES; Vector++) { /* Set the IDT to handle unexpected interrupts */ - ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); } /* Setup IDT handlers for known interrupts and traps */ - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x00, ArpTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x01, ArpTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x03, ArpTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x04, ArpTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x05, ArpTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x06, ArpTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x07, ArpTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x09, ArpTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0A, ArpTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0B, ArpTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0C, ArpTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x10, ArpTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x11, ArpTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x12, ArpTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x13, ArpTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2A, ArpTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2B, ArpTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2C, ArpTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2D, ArpTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); - ArpSetIdtGate(ProcessorBlock->IdtBase, 0x2E, ArpTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); + SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3); } /** @@ -292,18 +275,18 @@ ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) */ XTAPI VOID -ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, - IN PKGDTENTRY Gdt, - IN PKIDTENTRY Idt, - IN PKTSS Tss, - IN PVOID DpcStack) +ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) { /* Set processor block and processor control block */ ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; /* Set GDT, IDT and TSS descriptors */ - ProcessorBlock->GdtBase = Gdt; + ProcessorBlock->GdtBase = (PKGDTENTRY)(PVOID)Gdt; ProcessorBlock->IdtBase = Idt; ProcessorBlock->TssBase = Tss; @@ -323,7 +306,7 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->Prcb.CurrentThread = &KeInitialThread.ThreadControlBlock; ProcessorBlock->Prcb.CurrentThread->ApcState.Process = &KeInitialProcess.ProcessControlBlock; ProcessorBlock->Prcb.IdleThread = &KeInitialThread.ThreadControlBlock; - ProcessorBlock->Prcb.NextThread = NULL; + ProcessorBlock->Prcb.NextThread = nullptr; /* Set initial runlevel */ ProcessorBlock->RunLevel = PASSIVE_LEVEL; @@ -338,13 +321,13 @@ ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpInitializeProcessorRegisters(VOID) +ProcSup::InitializeProcessorRegisters(VOID) { /* Clear EFLAGS register */ - ArWriteEflagsRegister(0); + CpuFunc::WriteEflagsRegister(0); /* Enable write-protection */ - ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_WP); + CpuFunc::WriteControlRegister(0, CpuFunc::ReadControlRegister(0) | CR0_WP); } /** @@ -374,12 +357,12 @@ ArpInitializeProcessorRegisters(VOID) */ XTAPI VOID -ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, - OUT PKGDTENTRY *Gdt, - OUT PKTSS *Tss, - OUT PKPROCESSOR_BLOCK *ProcessorBlock, - OUT PVOID *KernelBootStack, - OUT PVOID *KernelFaultStack) +ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, + OUT PKGDTENTRY *Gdt, + OUT PKTSS *Tss, + OUT PKPROCESSOR_BLOCK *ProcessorBlock, + OUT PVOID *KernelBootStack, + OUT PVOID *KernelFaultStack) { UINT_PTR Address; @@ -394,15 +377,15 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, *KernelFaultStack = (PVOID)Address; /* Assign a space for GDT and advance */ - *Gdt = (PVOID)Address; + *Gdt = (PKGDTENTRY)(PVOID)Address; Address += sizeof(ArInitialGdt); /* Assign a space for Processor Block and advance */ - *ProcessorBlock = (PVOID)Address; + *ProcessorBlock = (PKPROCESSOR_BLOCK)(PVOID)Address; Address += sizeof(ArInitialProcessorBlock); /* Assign a space for TSS */ - *Tss = (PVOID)Address; + *Tss = (PKTSS)(PVOID)Address; } /** @@ -414,13 +397,13 @@ ArpInitializeProcessorStructures(IN PVOID ProcessorStructures, */ XTAPI VOID -ArpInitializeSegments(VOID) +ProcSup::InitializeSegments(VOID) { /* Initialize segments */ - ArLoadSegment(SEGMENT_CS, KGDT_R0_CODE); - ArLoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); - ArLoadSegment(SEGMENT_FS, KGDT_R0_PB); + CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); + CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); + CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB); } /** @@ -435,9 +418,9 @@ ArpInitializeSegments(VOID) */ XTAPI VOID -ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelBootStack, - IN PVOID KernelFaultStack) +ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelBootStack, + IN PVOID KernelFaultStack) { /* Clear I/O map */ RtlSetMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, 0xFF, IOPM_FULL_SIZE); @@ -468,8 +451,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; /* Initialize task gates for DoubleFault and NMI traps */ - ArpSetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); - ArpSetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); + SetDoubleFaultTssEntry(ProcessorBlock, KernelFaultStack); + SetNonMaskableInterruptTssEntry(ProcessorBlock, KernelFaultStack); } /** @@ -484,8 +467,8 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack) +ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack) { PKGDTENTRY TaskGateEntry, TssEntry; PKTSS Tss; @@ -498,20 +481,20 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; /* Initialize DoubleFault TSS and set initial state */ - Tss = (PKTSS)ArpDoubleFaultTss; + Tss = (PKTSS)DoubleFaultTss; Tss->IoMapBase = sizeof(KTSS); Tss->Flags = 0; Tss->LDT = KGDT_R0_LDT; - Tss->CR3 = ArReadControlRegister(3); + Tss->CR3 = CpuFunc::ReadControlRegister(3); Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack; - Tss->Eip = PtrToUlong(ArpHandleTrap08); + Tss->Eip = PtrToUlong(ArTrap0x08); Tss->Cs = KGDT_R0_CODE; Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Fs = KGDT_R0_PB; Tss->Ss0 = KGDT_R0_DATA; - ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); /* Setup DoubleFault TSS entry in Global Descriptor Table */ TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); @@ -555,13 +538,13 @@ ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, */ XTAPI VOID -ArpSetGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONG_PTR Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode) +ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) { PKGDTENTRY GdtEntry; UCHAR Granularity; @@ -601,6 +584,39 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.Type = (Type & 0x1F); } +/** + * Updates an existing i686 GDT entry with new base address. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONG_PTR Base) +{ + PKGDTENTRY GdtEntry; + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG_PTR)Gdt + (Selector & ~RPL_MASK)); + + /* Set new GDT descriptor base */ + GdtEntry->BaseLow = (Base & 0xFFFF); + GdtEntry->Bytes.BaseMiddle = ((Base >> 16) & 0xFF); + GdtEntry->Bytes.BaseHigh = ((Base >> 24) & 0xFF); +} + /** * Fills in a call, interrupt, task or trap gate entry. * @@ -628,12 +644,12 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, */ XTAPI VOID -ArpSetIdtGate(IN PKIDTENTRY Idt, - IN USHORT Vector, - IN PVOID Handler, - IN USHORT Selector, - IN USHORT Ist, - IN USHORT Access) +ProcSup::SetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) { /* Setup the gate */ Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); @@ -654,8 +670,8 @@ ArpSetIdtGate(IN PKIDTENTRY Idt, */ XTAPI VOID -ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, - IN PVOID KernelFaultStack) +ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, + IN PVOID KernelFaultStack) { PKGDTENTRY TaskGateEntry, TssEntry; PKTSS Tss; @@ -668,19 +684,19 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; /* Initialize NMI TSS and set initial state */ - Tss = (PKTSS)ArpNonMaskableInterruptTss; + Tss = (PKTSS)NonMaskableInterruptTss; Tss->IoMapBase = sizeof(KTSS); Tss->Flags = 0; Tss->LDT = KGDT_R0_LDT; Tss->CR3 = ArReadControlRegister(3); Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack; - Tss->Eip = PtrToUlong(ArpHandleTrap02); + Tss->Eip = PtrToUlong(ArTrap0x02); Tss->Cs = KGDT_R0_CODE; Tss->Ds = KGDT_R3_DATA | RPL_MASK; Tss->Es = KGDT_R3_DATA | RPL_MASK; Tss->Fs = KGDT_R0_PB; - ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + CpuFunc::StoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); /* Setup NMI TSS entry in Global Descriptor Table */ TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); @@ -693,3 +709,24 @@ ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, TssEntry->Bits.Present = 1; TssEntry->Bits.Type = I686_TSS; } + +} /* namespace */ + + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +PVOID +ArGetBootStack(VOID) +{ + return AR::ProcSup::GetBootStack(); +} + +/* TEMPORARY FOR COMPATIBILITY WITH C CODE */ +XTCLINK +XTAPI +VOID +ArInitializeProcessor(IN PVOID ProcessorStructures) +{ + AR::ProcSup::InitializeProcessor(ProcessorStructures); +} diff --git a/xtoskrnl/ar/i686/traps.c b/xtoskrnl/ar/i686/traps.cc similarity index 80% rename from xtoskrnl/ar/i686/traps.c rename to xtoskrnl/ar/i686/traps.cc index 031d9e2..b3e5db8 100644 --- a/xtoskrnl/ar/i686/traps.c +++ b/xtoskrnl/ar/i686/traps.cc @@ -1,14 +1,18 @@ /** * PROJECT: ExectOS * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/ar/i686/traps.c + * FILE: xtoskrnl/ar/i686/traps.cc * DESCRIPTION: I686 system traps * DEVELOPERS: Rafal Kupiec */ -#include +#include +/* Architecture-specific Library */ +namespace AR +{ + /** * Dispatches the trap provided by common trap handler. * @@ -21,110 +25,110 @@ */ XTCDECL VOID -ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) +Traps::DispatchTrap(IN PKTRAP_FRAME TrapFrame) { /* Check vector and call appropriate handler */ switch(TrapFrame->Vector) { case 0x00: /* Divide By Zero exception */ - ArpHandleTrap00(TrapFrame); + HandleTrap00(TrapFrame); break; case 0x01: /* Debug exception */ - ArpHandleTrap01(TrapFrame); + HandleTrap01(TrapFrame); break; case 0x02: /* Non-Maskable Interrupt (NMI) */ - ArpHandleTrap02(TrapFrame); + HandleTrap02(TrapFrame); break; case 0x03: /* INT3 instruction executed */ - ArpHandleTrap03(TrapFrame); + HandleTrap03(TrapFrame); break; case 0x04: /* Overflow exception */ - ArpHandleTrap04(TrapFrame); + HandleTrap04(TrapFrame); break; case 0x05: /* Bound Range Exceeded exception */ - ArpHandleTrap05(TrapFrame); + HandleTrap05(TrapFrame); break; case 0x06: /* Invalid Opcode exception */ - ArpHandleTrap06(TrapFrame); + HandleTrap06(TrapFrame); break; case 0x07: /* Device Not Available exception */ - ArpHandleTrap07(TrapFrame); + HandleTrap07(TrapFrame); break; case 0x08: /* Double Fault exception */ - ArpHandleTrap08(TrapFrame); + HandleTrap08(TrapFrame); break; case 0x09: /* Segment Overrun exception */ - ArpHandleTrap09(TrapFrame); + HandleTrap09(TrapFrame); break; case 0x0A: /* Invalid TSS exception */ - ArpHandleTrap0A(TrapFrame); + HandleTrap0A(TrapFrame); break; case 0x0B: /* Segment Not Present exception */ - ArpHandleTrap0B(TrapFrame); + HandleTrap0B(TrapFrame); break; case 0x0C: /* Stack Segment Fault exception */ - ArpHandleTrap0C(TrapFrame); + HandleTrap0C(TrapFrame); break; case 0x0D: /* General Protection Fault (GPF) exception*/ - ArpHandleTrap0D(TrapFrame); + HandleTrap0D(TrapFrame); break; case 0x0E: /* Page Fault exception */ - ArpHandleTrap0E(TrapFrame); + HandleTrap0E(TrapFrame); break; case 0x10: /* X87 Floating-Point exception */ - ArpHandleTrap10(TrapFrame); + HandleTrap10(TrapFrame); break; case 0x11: /* Alignment Check exception */ - ArpHandleTrap11(TrapFrame); + HandleTrap11(TrapFrame); break; case 0x12: /* Machine Check exception */ - ArpHandleTrap12(TrapFrame); + HandleTrap12(TrapFrame); break; case 0x13: /* SIMD Floating-Point exception */ - ArpHandleTrap13(TrapFrame); + HandleTrap13(TrapFrame); break; case 0x2A: /* Tick Count service request */ - ArpHandleTrap2A(TrapFrame); + HandleTrap2A(TrapFrame); break; case 0x2B: /* User-mode callback return */ - ArpHandleTrap2B(TrapFrame); + HandleTrap2B(TrapFrame); break; case 0x2C: /* Assertion raised */ - ArpHandleTrap2C(TrapFrame); + HandleTrap2C(TrapFrame); break; case 0x2D: /* Debug-Service-Request raised */ - ArpHandleTrap2D(TrapFrame); + HandleTrap2D(TrapFrame); break; case 0x2E: /* System call service request */ - ArpHandleTrap2E(TrapFrame); + HandleTrap2E(TrapFrame); break; default: /* Unknown/Unexpected trap */ - ArpHandleTrapFF(TrapFrame); + HandleTrapFF(TrapFrame); break; } } @@ -141,7 +145,7 @@ ArpDispatchTrap(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap00(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Division-By-Zero Error (0x00)!\n"); for(;;); @@ -159,7 +163,7 @@ ArpHandleTrap00(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap01(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug exception (0x01)!\n"); for(;;); @@ -177,7 +181,7 @@ ArpHandleTrap01(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap02(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Non-Maskable-Interrupt (0x02)!\n"); for(;;); @@ -195,7 +199,7 @@ ArpHandleTrap02(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap03(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled INT3 (0x03)!\n"); for(;;); @@ -213,7 +217,7 @@ ArpHandleTrap03(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap04(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Overflow exception (0x04)!\n"); for(;;); @@ -231,7 +235,7 @@ ArpHandleTrap04(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap05(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Bound-Range-Exceeded exception (0x05)!\n"); for(;;); @@ -249,7 +253,7 @@ ArpHandleTrap05(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap06(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid Opcode exception (0x06)!\n"); for(;;); @@ -267,7 +271,7 @@ ArpHandleTrap06(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap07(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Device Not Available exception (0x07)!\n"); for(;;); @@ -285,7 +289,7 @@ ArpHandleTrap07(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap08(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Double-Fault exception (0x08)!\n"); for(;;); @@ -303,7 +307,7 @@ ArpHandleTrap08(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap09(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Overrun exception (0x09)!\n"); for(;;); @@ -321,7 +325,7 @@ ArpHandleTrap09(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Invalid-TSS exception (0x0A)!\n"); for(;;); @@ -339,7 +343,7 @@ ArpHandleTrap0A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Segment-Not-Present exception (0x0B)!\n"); for(;;); @@ -357,7 +361,7 @@ ArpHandleTrap0B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Stack-Segment-Fault exception (0x0C)!\n"); for(;;); @@ -375,7 +379,7 @@ ArpHandleTrap0C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled General-Protection-Fault (0x0D)!\n"); for(;;); @@ -393,7 +397,7 @@ ArpHandleTrap0D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap0E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Page-Fault exception (0x0E)!\n"); for(;;); @@ -411,7 +415,7 @@ ArpHandleTrap0E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap10(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled x87 Floating-Point exception (0x10)!\n"); for(;;); @@ -429,7 +433,7 @@ ArpHandleTrap10(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap11(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Alignment-Check exception (0x11)!\n"); for(;;); @@ -447,7 +451,7 @@ ArpHandleTrap11(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap12(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Machine-Check exception (0x12)!\n"); for(;;); @@ -465,7 +469,7 @@ ArpHandleTrap12(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap13(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled SIMD Floating-Point exception (0x13)!\n"); for(;;); @@ -483,7 +487,7 @@ ArpHandleTrap13(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2A(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled Tick Count service request (0x2A)!\n"); } @@ -500,7 +504,7 @@ ArpHandleTrap2A(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2B(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled Callback return service request (0x2B)!\n"); } @@ -517,7 +521,7 @@ ArpHandleTrap2B(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2C(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Assertion (0x2C)!\n"); for(;;); @@ -535,7 +539,7 @@ ArpHandleTrap2C(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2D(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Debug-Service-Request (0x2D)!\n"); for(;;); @@ -553,7 +557,7 @@ ArpHandleTrap2D(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrap2E(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Unhandled system call (0x2E)!\n"); } @@ -570,8 +574,28 @@ ArpHandleTrap2E(IN PKTRAP_FRAME TrapFrame) */ XTCDECL VOID -ArpHandleTrapFF(IN PKTRAP_FRAME TrapFrame) +Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame) { DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n"); for(;;); } + +} /* namespace */ + +/** + * C-linkage wrapper for dispatching the trap provided by common trap handler. + * + * @param TrapFrame + * Supplies a kernel trap frame pushed by common trap handler on the stack. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCLINK +XTCDECL +VOID +ArDispatchTrap(IN PKTRAP_FRAME TrapFrame) +{ + AR::Traps::DispatchTrap(TrapFrame); +} diff --git a/xtoskrnl/includes/amd64/ari.h b/xtoskrnl/includes/amd64/ari.h index 1b63daa..fa461b1 100644 --- a/xtoskrnl/includes/amd64/ari.h +++ b/xtoskrnl/includes/amd64/ari.h @@ -25,6 +25,10 @@ XTCDECL VOID ArFlushTlb(VOID); +XTAPI +PVOID +ArGetBootStack(VOID); + XTCDECL ULONG ArGetCpuFlags(VOID); @@ -431,4 +435,8 @@ XTCDECL VOID ArpTrap0xE1(VOID); +XTCDECL +VOID +ArpTrap0xFF(VOID); + #endif /* __XTOSKRNL_AMD64_ARI_H */ diff --git a/xtoskrnl/includes/amd64/kei.h b/xtoskrnl/includes/amd64/kei.h index de0da65..35c6ae2 100644 --- a/xtoskrnl/includes/amd64/kei.h +++ b/xtoskrnl/includes/amd64/kei.h @@ -55,6 +55,6 @@ KepStartKernel(VOID); XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack); +KepSwitchBootStack(); #endif /* __XTOSKRNL_AMD64_KEI_H */ diff --git a/xtoskrnl/includes/ar.hh b/xtoskrnl/includes/ar.hh new file mode 100644 index 0000000..d01dbb9 --- /dev/null +++ b/xtoskrnl/includes/ar.hh @@ -0,0 +1,18 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/ar.hh + * DESCRIPTION: + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_AR_HH +#define __XTOSKRNL_AR_HH + +#include + +#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 */ diff --git a/xtoskrnl/includes/ar/amd64/cpufunc.hh b/xtoskrnl/includes/ar/amd64/cpufunc.hh new file mode 100644 index 0000000..856d3d2 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/cpufunc.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_CPUFUNC_HH +#define __XTOSKRNL_AR_CPUFUNC_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/ar/amd64/procsup.hh b/xtoskrnl/includes/ar/amd64/procsup.hh new file mode 100644 index 0000000..6283701 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/procsup.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_PROCSUP_HH +#define __XTOSKRNL_AR_PROCSUP_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/ar/amd64/traps.hh b/xtoskrnl/includes/ar/amd64/traps.hh new file mode 100644 index 0000000..a332367 --- /dev/null +++ b/xtoskrnl/includes/ar/amd64/traps.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_TRAPS_HH +#define __XTOSKRNL_AR_TRAPS_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/ar/i686/cpufunc.hh b/xtoskrnl/includes/ar/i686/cpufunc.hh new file mode 100644 index 0000000..b05c696 --- /dev/null +++ b/xtoskrnl/includes/ar/i686/cpufunc.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_CPUFUNC_HH +#define __XTOSKRNL_AR_CPUFUNC_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/ar/i686/procsup.hh b/xtoskrnl/includes/ar/i686/procsup.hh new file mode 100644 index 0000000..d6c13ba --- /dev/null +++ b/xtoskrnl/includes/ar/i686/procsup.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_PROCSUP_HH +#define __XTOSKRNL_AR_PROCSUP_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/ar/i686/traps.hh b/xtoskrnl/includes/ar/i686/traps.hh new file mode 100644 index 0000000..4b90e88 --- /dev/null +++ b/xtoskrnl/includes/ar/i686/traps.hh @@ -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 + */ + +#ifndef __XTOSKRNL_AR_TRAPS_HH +#define __XTOSKRNL_AR_TRAPS_HH + +#include + + +/* 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 */ diff --git a/xtoskrnl/includes/i686/ari.h b/xtoskrnl/includes/i686/ari.h index 377e7f3..4332312 100644 --- a/xtoskrnl/includes/i686/ari.h +++ b/xtoskrnl/includes/i686/ari.h @@ -25,6 +25,10 @@ XTCDECL VOID ArFlushTlb(VOID); +XTAPI +PVOID +ArGetBootStack(VOID); + XTCDECL ULONG ArGetCpuFlags(VOID); diff --git a/xtoskrnl/includes/i686/kei.h b/xtoskrnl/includes/i686/kei.h index 5d37e6f..daa9e51 100644 --- a/xtoskrnl/includes/i686/kei.h +++ b/xtoskrnl/includes/i686/kei.h @@ -55,6 +55,6 @@ KepStartKernel(VOID); XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack); +KepSwitchBootStack(); #endif /* __XTOSKRNL_I686_KEI_H */ diff --git a/xtoskrnl/includes/xtos.hh b/xtoskrnl/includes/xtos.hh new file mode 100644 index 0000000..71edec8 --- /dev/null +++ b/xtoskrnl/includes/xtos.hh @@ -0,0 +1,29 @@ +/** + * 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 + */ + + +/* 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 + +/* XT OS version */ +#include + +/* Kernel specific headers */ +#include +} + + + +#include diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.c index 610e4ef..3eb19a6 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.c @@ -100,7 +100,7 @@ KepStartKernel(VOID) CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArKernelBootStack, TRUE); + KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -114,16 +114,19 @@ KepStartKernel(VOID) } /** - * Switches to a new kernel boot stack. + * Switches execution to a new boot stack and transfers control to the KepStartKernel() routine. * - * @return This routine does not return any value + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack) +KepSwitchBootStack() { + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + /* Discard old stack frame, switch stack and jump to KepStartKernel() */ __asm__ volatile("mov %0, %%rdx\n" "xor %%rbp, %%rbp\n" @@ -133,5 +136,6 @@ KepSwitchBootStack(IN ULONG_PTR Stack) : : "m" (Stack), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), - "p" (KepStartKernel)); + "p" (KepStartKernel) + : "rdx", "rbp", "rsp", "memory"); } diff --git a/xtoskrnl/ke/i686/krnlinit.c b/xtoskrnl/ke/i686/krnlinit.c index 6d0d725..51d7f11 100644 --- a/xtoskrnl/ke/i686/krnlinit.c +++ b/xtoskrnl/ke/i686/krnlinit.c @@ -100,7 +100,7 @@ KepStartKernel(VOID) CurrentProcess->Quantum = MAXCHAR; /* Initialize Idle thread */ - KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArKernelBootStack, TRUE); + KeInitializeThread(CurrentProcess, CurrentThread, NULL, NULL, NULL, NULL, NULL, ArGetBootStack(), TRUE); CurrentThread->NextProcessor = Prcb->CpuNumber; CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->State = Running; @@ -114,16 +114,19 @@ KepStartKernel(VOID) } /** - * Switches to a new kernel boot stack. + * Switches execution to a new boot stack and transfers control to the specified routine. * - * @return This routine does not return any value + * @return This routine does not return any value. * * @since XT 1.0 */ XTAPI VOID -KepSwitchBootStack(IN ULONG_PTR Stack) +KepSwitchBootStack() { + /* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ + ULONG_PTR Stack = ((ULONG_PTR)ArGetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); + /* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */ __asm__ volatile("mov %0, %%edx\n" "xor %%ebp, %%ebp\n" @@ -135,5 +138,6 @@ KepSwitchBootStack(IN ULONG_PTR Stack) : "m" (Stack), "i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (CR0_EM | CR0_MP | CR0_TS), - "p" (KepStartKernel)); + "p" (KepStartKernel) + : "edx", "ebp", "esp", "memory"); } diff --git a/xtoskrnl/ke/krnlinit.c b/xtoskrnl/ke/krnlinit.c index e8705a2..b96a5e3 100644 --- a/xtoskrnl/ke/krnlinit.c +++ b/xtoskrnl/ke/krnlinit.c @@ -68,6 +68,6 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) /* Raise to HIGH runlevel */ KeRaiseRunLevel(HIGH_LEVEL); - /* Switch the boot stack, setting the pointer to the top of the buffer and aligning it as required by the ABI */ - KepSwitchBootStack(((ULONG_PTR)&ArKernelBootStack + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1)); + /* Switch the boot stack and transfer control to the KepStartKernel() routine */ + KepSwitchBootStack(); }