Compare commits

5 Commits

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ include_directories(
# Specify list of library source code files # Specify list of library source code files
list(APPEND LIBXTOS_SOURCE list(APPEND LIBXTOS_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c
${XTOSKRNL_SOURCE_DIR}/rtl/globals.c ${XTOSKRNL_SOURCE_DIR}/rtl/globals.c
@@ -25,11 +25,12 @@ list(APPEND LIBXTOS_SOURCE
list(APPEND XTOSKRNL_SOURCE list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/archsup.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/boot.S
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/data.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.cc
${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.c ${XTOSKRNL_SOURCE_DIR}/ex/exports.cc
${XTOSKRNL_SOURCE_DIR}/ex/rundown.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.c ${XTOSKRNL_SOURCE_DIR}/hl/acpi.c
${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.c

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

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

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

View File

@@ -1,14 +1,17 @@
/** /**
* PROJECT: ExectOS * PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory * COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ex/rundown.c * FILE: xtoskrnl/ex/rundown.cc
* DESCRIPTION: Rundown protection mechanism * DESCRIPTION: Rundown protection mechanism
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org> * DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/ */
#include <xtos.h> #include <xtos.hh>
namespace EX
{
/** /**
* Acquires the rundown protection for given descriptor. * Acquires the rundown protection for given descriptor.
* *
@@ -21,7 +24,7 @@
*/ */
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
@@ -69,7 +72,7 @@ ExAcquireRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE); RtlAtomicExchangePointer(&Descriptor->Ptr, (PVOID)EX_RUNDOWN_ACTIVE);
} }
@@ -86,7 +89,7 @@ ExCompleteRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
/* Reset descriptor counter */ /* Reset descriptor counter */
Descriptor->Count = 0; Descriptor->Count = 0;
@@ -104,7 +107,7 @@ ExInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
RtlAtomicExchangePointer(&Descriptor->Ptr, NULL); RtlAtomicExchangePointer(&Descriptor->Ptr, NULL);
} }
@@ -121,7 +124,7 @@ ExReInitializeRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
ULONG_PTR CurrentValue, NewValue; ULONG_PTR CurrentValue, NewValue;
PEX_RUNDOWN_WAIT_BLOCK WaitBlock; PEX_RUNDOWN_WAIT_BLOCK WaitBlock;
@@ -172,7 +175,9 @@ ExReleaseRundownProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
ExWaitForRundownProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor) Rundown::WaitForProtectionRelease(IN PEX_RUNDOWN_REFERENCE Descriptor)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
} /* namespace */

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

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

View File

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

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

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

View File

@@ -100,7 +100,7 @@ KepStartKernel(VOID)
CurrentProcess->Quantum = MAXCHAR; CurrentProcess->Quantum = MAXCHAR;
/* Initialize Idle thread */ /* 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; 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 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID 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() */ /* Discard old stack frame, switch stack and jump to KepStartKernel() */
__asm__ volatile("mov %0, %%rdx\n" __asm__ volatile("mov %0, %%rdx\n"
"xor %%rbp, %%rbp\n" "xor %%rbp, %%rbp\n"
@@ -133,5 +136,6 @@ KepSwitchBootStack(IN ULONG_PTR Stack)
: :
: "m" (Stack), : "m" (Stack),
"i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (FLOATING_SAVE_AREA_SIZE | KEXCEPTION_FRAME_SIZE | KSWITCH_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
"p" (KepStartKernel)); "p" (KepStartKernel)
: "rdx", "rbp", "rsp", "memory");
} }

View File

@@ -100,7 +100,7 @@ KepStartKernel(VOID)
CurrentProcess->Quantum = MAXCHAR; CurrentProcess->Quantum = MAXCHAR;
/* Initialize Idle thread */ /* 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; 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 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID 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() */ /* Discard old stack frame, switch stack, make space for NPX and jump to KepStartKernel() */
__asm__ volatile("mov %0, %%edx\n" __asm__ volatile("mov %0, %%edx\n"
"xor %%ebp, %%ebp\n" "xor %%ebp, %%ebp\n"
@@ -135,5 +138,6 @@ KepSwitchBootStack(IN ULONG_PTR Stack)
: "m" (Stack), : "m" (Stack),
"i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE), "i" (KTRAP_FRAME_ALIGN | KTRAP_FRAME_SIZE | NPX_FRAME_SIZE | KRETURN_ADDRESS_SIZE),
"i" (CR0_EM | CR0_MP | CR0_TS), "i" (CR0_EM | CR0_MP | CR0_TS),
"p" (KepStartKernel)); "p" (KepStartKernel)
: "edx", "ebp", "esp", "memory");
} }

View File

@@ -68,6 +68,6 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
/* Raise to HIGH runlevel */ /* Raise to HIGH runlevel */
KeRaiseRunLevel(HIGH_LEVEL); KeRaiseRunLevel(HIGH_LEVEL);
/* Switch the boot stack, setting the pointer to the top of the buffer and aligning it as required by the ABI */ /* Switch the boot stack and transfer control to the KepStartKernel() routine */
KepSwitchBootStack(((ULONG_PTR)&ArKernelBootStack + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1)); KepSwitchBootStack();
} }