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

This commit is contained in:
2025-09-08 15:29:13 +02:00
parent 27fec1bacb
commit c8dc2a1407
42 changed files with 2042 additions and 695 deletions

View File

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

View File

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

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

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

View File

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

View File

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

View File

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