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