forked from xt-sys/exectos
Implement NMI stack handling via IST
This commit is contained in:
@@ -58,6 +58,7 @@
|
|||||||
#define KIDT_IST_RESERVED 0
|
#define KIDT_IST_RESERVED 0
|
||||||
#define KIDT_IST_PANIC 1
|
#define KIDT_IST_PANIC 1
|
||||||
#define KIDT_IST_MCA 2
|
#define KIDT_IST_MCA 2
|
||||||
|
#define KIDT_IST_NMI 3
|
||||||
|
|
||||||
/* AMD64 Segment Types */
|
/* AMD64 Segment Types */
|
||||||
#define AMD64_TASK_GATE 0x5
|
#define AMD64_TASK_GATE 0x5
|
||||||
|
|||||||
@@ -26,3 +26,6 @@ KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
|||||||
|
|
||||||
/* Initial TSS */
|
/* Initial TSS */
|
||||||
KTSS AR::ProcSup::InitialTss;
|
KTSS AR::ProcSup::InitialTss;
|
||||||
|
|
||||||
|
/* Initial kernel NMI stack */
|
||||||
|
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||||
|
|||||||
@@ -136,8 +136,8 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||||
{
|
{
|
||||||
|
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||||
PVOID KernelBootStack, KernelFaultStack;
|
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
PKGDTENTRY Gdt;
|
PKGDTENTRY Gdt;
|
||||||
PKIDTENTRY Idt;
|
PKIDTENTRY Idt;
|
||||||
@@ -148,7 +148,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
|||||||
{
|
{
|
||||||
/* Assign CPU structures from provided buffer */
|
/* Assign CPU structures from provided buffer */
|
||||||
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
InitializeProcessorStructures(ProcessorStructures, &Gdt, &Tss, &ProcessorBlock,
|
||||||
&KernelBootStack, &KernelFaultStack);
|
&KernelBootStack, &KernelFaultStack, &KernelNmiStack);
|
||||||
|
|
||||||
/* Use global IDT */
|
/* Use global IDT */
|
||||||
Idt = InitialIdt;
|
Idt = InitialIdt;
|
||||||
@@ -161,6 +161,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
|||||||
Tss = &InitialTss;
|
Tss = &InitialTss;
|
||||||
KernelBootStack = &BootStack;
|
KernelBootStack = &BootStack;
|
||||||
KernelFaultStack = &FaultStack;
|
KernelFaultStack = &FaultStack;
|
||||||
|
KernelNmiStack = &NmiStack;
|
||||||
ProcessorBlock = &InitialProcessorBlock;
|
ProcessorBlock = &InitialProcessorBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +171,7 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
|||||||
/* Initialize GDT, IDT and TSS */
|
/* Initialize GDT, IDT and TSS */
|
||||||
InitializeGdt(ProcessorBlock);
|
InitializeGdt(ProcessorBlock);
|
||||||
InitializeIdt(ProcessorBlock);
|
InitializeIdt(ProcessorBlock);
|
||||||
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack);
|
InitializeTss(ProcessorBlock, KernelBootStack, KernelFaultStack, KernelNmiStack);
|
||||||
|
|
||||||
/* Set GDT and IDT descriptors */
|
/* Set GDT and IDT descriptors */
|
||||||
GdtDescriptor.Base = Gdt;
|
GdtDescriptor.Base = Gdt;
|
||||||
@@ -256,7 +257,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
/* Setup IDT handlers for known interrupts and traps */
|
/* Setup IDT handlers for known interrupts and traps */
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_NMI, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
|
||||||
@@ -277,7 +278,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
|||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrapEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArInterruptEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -429,7 +430,8 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
OUT PKTSS *Tss,
|
OUT PKTSS *Tss,
|
||||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||||
OUT PVOID *KernelBootStack,
|
OUT PVOID *KernelBootStack,
|
||||||
OUT PVOID *KernelFaultStack)
|
OUT PVOID *KernelFaultStack,
|
||||||
|
OUT PVOID *KernelNmiStack)
|
||||||
{
|
{
|
||||||
UINT_PTR Address;
|
UINT_PTR Address;
|
||||||
|
|
||||||
@@ -440,8 +442,12 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
|||||||
*KernelBootStack = (PVOID)Address;
|
*KernelBootStack = (PVOID)Address;
|
||||||
Address += KERNEL_STACK_SIZE;
|
Address += KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
/* Assign a space for kernel fault stack, no advance needed as stack grows down */
|
/* Assign a space for kernel fault stack and advance */
|
||||||
*KernelFaultStack = (PVOID)Address;
|
*KernelFaultStack = (PVOID)Address;
|
||||||
|
Address += KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
|
/* Assign a space for kernel NMI stack, no advance needed as stack grows down */
|
||||||
|
*KernelNmiStack = (PVOID)Address;
|
||||||
|
|
||||||
/* Assign a space for GDT and advance */
|
/* Assign a space for GDT and advance */
|
||||||
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
*Gdt = (PKGDTENTRY)(PVOID)Address;
|
||||||
@@ -492,7 +498,8 @@ XTAPI
|
|||||||
VOID
|
VOID
|
||||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelBootStack,
|
IN PVOID KernelBootStack,
|
||||||
IN PVOID KernelFaultStack)
|
IN PVOID KernelFaultStack,
|
||||||
|
IN PVOID KernelNmiStack)
|
||||||
{
|
{
|
||||||
/* Fill TSS with zeroes */
|
/* Fill TSS with zeroes */
|
||||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||||
@@ -502,6 +509,8 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
|||||||
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
ProcessorBlock->TssBase->Rsp0 = (ULONG_PTR)KernelBootStack;
|
||||||
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
ProcessorBlock->TssBase->Ist[KIDT_IST_PANIC] = (ULONG_PTR)KernelFaultStack;
|
||||||
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
ProcessorBlock->TssBase->Ist[KIDT_IST_MCA] = (ULONG_PTR)KernelFaultStack;
|
||||||
|
ProcessorBlock->TssBase->Ist[KIDT_IST_NMI] = (ULONG_PTR)KernelNmiStack;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace AR
|
|||||||
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
STATIC KIDTENTRY InitialIdt[IDT_ENTRIES];
|
||||||
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
STATIC KPROCESSOR_BLOCK InitialProcessorBlock;
|
||||||
STATIC KTSS InitialTss;
|
STATIC KTSS InitialTss;
|
||||||
|
STATIC UCHAR NmiStack[KERNEL_STACK_SIZE];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI PVOID GetBootStack(VOID);
|
STATIC XTAPI PVOID GetBootStack(VOID);
|
||||||
@@ -54,11 +55,13 @@ namespace AR
|
|||||||
OUT PKTSS *Tss,
|
OUT PKTSS *Tss,
|
||||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||||
OUT PVOID *KernelBootStack,
|
OUT PVOID *KernelBootStack,
|
||||||
OUT PVOID *KernelFaultStack);
|
OUT PVOID *KernelFaultStack,
|
||||||
|
OUT PVOID *KernelNmiStack);
|
||||||
STATIC XTAPI VOID InitializeSegments(VOID);
|
STATIC XTAPI VOID InitializeSegments(VOID);
|
||||||
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
STATIC XTAPI VOID InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||||
IN PVOID KernelBootStack,
|
IN PVOID KernelBootStack,
|
||||||
IN PVOID KernelFaultStack);
|
IN PVOID KernelFaultStack,
|
||||||
|
IN PVOID KernelNmiStack);
|
||||||
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
STATIC XTAPI VOID SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||||
IN USHORT Selector,
|
IN USHORT Selector,
|
||||||
IN ULONG_PTR Base,
|
IN ULONG_PTR Base,
|
||||||
|
|||||||
Reference in New Issue
Block a user