Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
a93ebbfb5b
|
|||
|
53726b5743
|
|||
|
71870cd178
|
|||
|
6f3b5b5e51
|
|||
|
6b689baa7a
|
|||
|
9ac64605d3
|
|||
|
102b357a75
|
|||
|
6eb0b4d982
|
|||
|
d8cb7c9242
|
|||
|
9002ac8b5c
|
|||
|
72a03f641d
|
|||
|
fe2e78f3c7
|
|||
|
6e4f0ba6e4
|
|||
|
19092eda2e
|
|||
|
b03cca65d8
|
|||
|
fec5bf65f1
|
|||
|
7836dbe147
|
|||
|
297aba248b
|
|||
|
d41c90f541
|
|||
|
f2c70d582a
|
|||
|
24c9ae321c
|
|||
|
7a18a2602f
|
@@ -15,7 +15,7 @@
|
||||
/* Minimal forward references for AR classes used by XTLDR */
|
||||
namespace AR
|
||||
{
|
||||
class CpuFunc
|
||||
class CpuFunctions
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
|
||||
@@ -25,7 +25,7 @@ namespace AR
|
||||
IN UINT_PTR Value);
|
||||
};
|
||||
|
||||
class ProcSup
|
||||
class ProcessorSupport
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
|
||||
@@ -1032,7 +1032,7 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu;
|
||||
LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol;
|
||||
LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;
|
||||
LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation;
|
||||
LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcessorSupport::GetTrampolineInformation;
|
||||
LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;
|
||||
LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;
|
||||
LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;
|
||||
@@ -1049,10 +1049,10 @@ Protocol::InstallXtLoaderProtocol()
|
||||
LoaderProtocol.Console.SetAttributes = Console::SetAttributes;
|
||||
LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition;
|
||||
LoaderProtocol.Console.Write = Console::Write;
|
||||
LoaderProtocol.Cpu.CpuId = AR::CpuFunc::CpuId;
|
||||
LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister;
|
||||
LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister;
|
||||
LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister;
|
||||
LoaderProtocol.Cpu.CpuId = AR::CpuFunctions::CpuId;
|
||||
LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunctions::ReadControlRegister;
|
||||
LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunctions::ReadModelSpecificRegister;
|
||||
LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunctions::WriteControlRegister;
|
||||
LoaderProtocol.Debug.Print = Debug::Print;
|
||||
LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume;
|
||||
LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume;
|
||||
|
||||
@@ -85,6 +85,7 @@ GenerateAssemblyDefinitions(VOID)
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
|
||||
@@ -59,6 +59,7 @@ GenerateAssemblyDefinitions(VOID)
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
|
||||
ADK_OFFSET(PROCESSOR_START_BLOCK, Started);
|
||||
|
||||
@@ -18,56 +18,56 @@
|
||||
|
||||
|
||||
/* Selector masks */
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
#define MODE_MASK 0x0001
|
||||
#define RPL_MASK 0x0003
|
||||
|
||||
/* GDT selector names */
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
#define KGDT_NULL 0x0000
|
||||
#define KGDT_R0_CMCODE 0x0008
|
||||
#define KGDT_R0_CODE 0x0010
|
||||
#define KGDT_R0_DATA 0x0018
|
||||
#define KGDT_R3_CMCODE 0x0020
|
||||
#define KGDT_R3_DATA 0x0028
|
||||
#define KGDT_R3_CODE 0x0030
|
||||
#define KGDT_SYS_TSS 0x0040
|
||||
#define KGDT_R3_CMTEB 0x0050
|
||||
#define KGDT_R0_LDT 0x0060
|
||||
#define KGDT_ALIAS 0x0070
|
||||
|
||||
/* GDT descriptor privilege levels */
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
#define KGDT_DPL_SYSTEM 0
|
||||
#define KGDT_DPL_USER 3
|
||||
|
||||
/* GDT descriptor properties */
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
#define KGDT_DESCRIPTOR_ACCESSED 0x01
|
||||
#define KGDT_DESCRIPTOR_READ_WRITE 0x02
|
||||
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
|
||||
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
|
||||
#define KGDT_DESCRIPTOR_CONFORMING 0x04
|
||||
#define KGDT_DESCRIPTOR_CODE 0x08
|
||||
|
||||
/* GDT descriptor type codes */
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
#define KGDT_TYPE_NONE 0x00
|
||||
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
|
||||
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
|
||||
|
||||
/* IDT access levels */
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
#define KIDT_ACCESS_RING0 0x0
|
||||
#define KIDT_ACCESS_RING3 0x3
|
||||
|
||||
/* IDT Interrupt Stack Table entries */
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_NMI 3
|
||||
#define KIDT_IST_RESERVED 0
|
||||
#define KIDT_IST_PANIC 1
|
||||
#define KIDT_IST_MCA 2
|
||||
#define KIDT_IST_NMI 3
|
||||
|
||||
/* AMD64 Segment Types */
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
#define AMD64_TASK_GATE 0x5
|
||||
#define AMD64_TSS 0x9
|
||||
#define AMD64_ACTIVE_TSS 0xB
|
||||
#define AMD64_CALL_GATE 0xC
|
||||
#define AMD64_INTERRUPT_GATE 0xE
|
||||
#define AMD64_TRAP_GATE 0xF
|
||||
|
||||
/* Kernel CPU Standard Features */
|
||||
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
|
||||
@@ -126,33 +126,33 @@
|
||||
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
|
||||
|
||||
/* Context control flags */
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
#define CONTEXT_ARCHITECTURE 0x00100000
|
||||
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
|
||||
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
|
||||
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
|
||||
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
|
||||
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
|
||||
|
||||
/* Interrupt request levels definitions */
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
#define PASSIVE_LEVEL 0
|
||||
#define LOW_LEVEL 0
|
||||
#define APC_LEVEL 1
|
||||
#define DISPATCH_LEVEL 2
|
||||
#define CMC_LEVEL 5
|
||||
#define DEVICE1_LEVEL 6
|
||||
#define DEVICE2_LEVEL 7
|
||||
#define DEVICE3_LEVEL 8
|
||||
#define DEVICE4_LEVEL 9
|
||||
#define DEVICE5_LEVEL 10
|
||||
#define DEVICE6_LEVEL 11
|
||||
#define DEVICE7_LEVEL 12
|
||||
#define SYNC_LEVEL 12
|
||||
#define CLOCK_LEVEL 13
|
||||
#define IPI_LEVEL 14
|
||||
#define DRS_LEVEL 14
|
||||
#define POWER_LEVEL 14
|
||||
#define PROFILE_LEVEL 15
|
||||
#define HIGH_LEVEL 15
|
||||
|
||||
/* Size of the exception area */
|
||||
#define EXCEPTION_AREA_SIZE 64
|
||||
@@ -183,6 +183,9 @@
|
||||
#define KTRAP_FRAME_ALIGN 0x10
|
||||
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
|
||||
|
||||
/* Initial stack reservation size */
|
||||
#define KTHREAD_STACK_OFFSET ((sizeof(KTHREAD_INIT_FRAME) + STACK_ALIGNMENT - 1) & ~(STACK_ALIGNMENT - 1))
|
||||
|
||||
/* Return address size pushed by 'call' instruction */
|
||||
#define KRETURN_ADDRESS_SIZE 0x8
|
||||
|
||||
@@ -532,6 +535,7 @@ typedef struct _PROCESSOR_START_BLOCK
|
||||
ULONG_PTR Cr3;
|
||||
ULONG_PTR Cr4;
|
||||
PVOID EntryPoint;
|
||||
PVOID InitialStack;
|
||||
PVOID ProcessorStructures;
|
||||
PVOID Stack;
|
||||
BOOLEAN Started;
|
||||
|
||||
@@ -119,9 +119,6 @@
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 64
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
@@ -201,6 +201,9 @@
|
||||
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
|
||||
#define NPX_FRAME_SIZE 0x210
|
||||
|
||||
/* Initial stack reservation size */
|
||||
#define KTHREAD_STACK_OFFSET ((sizeof(KTHREAD_INIT_FRAME) + STACK_ALIGNMENT - 1) & ~(STACK_ALIGNMENT - 1))
|
||||
|
||||
/* Number of supported extensions */
|
||||
#define MAXIMUM_SUPPORTED_EXTENSION 512
|
||||
|
||||
@@ -493,6 +496,7 @@ typedef struct _PROCESSOR_START_BLOCK
|
||||
ULONG_PTR Cr3;
|
||||
ULONG_PTR Cr4;
|
||||
PVOID EntryPoint;
|
||||
PVOID InitialStack;
|
||||
PVOID ProcessorStructures;
|
||||
PVOID Stack;
|
||||
BOOLEAN Started;
|
||||
|
||||
@@ -117,9 +117,6 @@
|
||||
/* Number of pool lists per page */
|
||||
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE)
|
||||
|
||||
/* Number of pool tracking tables */
|
||||
#define MM_POOL_TRACKING_TABLES 32
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
#ifndef __XTOS_ASSEMBLER__
|
||||
|
||||
@@ -14,51 +14,55 @@
|
||||
|
||||
|
||||
/* UUID string lengths */
|
||||
#define GUID_STRING_LENGTH 38
|
||||
#define PARTUUID_STRING_LENGTH 13
|
||||
#define GUID_STRING_LENGTH 38
|
||||
#define PARTUUID_STRING_LENGTH 13
|
||||
|
||||
/* Maximum double/integer value string length */
|
||||
#define MAX_DOUBLE_STRING_SIZE 15
|
||||
#define MAX_INTEGER_STRING_SIZE 25
|
||||
#define MAX_DOUBLE_STRING_SIZE 15
|
||||
#define MAX_INTEGER_STRING_SIZE 25
|
||||
|
||||
/* Floating point definitions */
|
||||
#define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL
|
||||
#define DOUBLE_EXPONENT_SHIFT 0x34
|
||||
#define DOUBLE_EXPONENT_BIAS 0x3FF
|
||||
#define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF
|
||||
#define DOUBLE_HIGH_VALUE_SHIFT 0x20
|
||||
#define DOUBLE_PRECISION 6
|
||||
#define DOUBLE_HEX_PRECISION 13
|
||||
#define DOUBLE_SCIENTIFIC_PRECISION -4
|
||||
#define DOUBLE_SIGN_BIT 0x8000000000000000ULL
|
||||
#define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL
|
||||
#define DOUBLE_EXPONENT_SHIFT 0x34
|
||||
#define DOUBLE_EXPONENT_BIAS 0x3FF
|
||||
#define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF
|
||||
#define DOUBLE_HIGH_VALUE_SHIFT 0x20
|
||||
#define DOUBLE_PRECISION 6
|
||||
#define DOUBLE_HEX_PRECISION 13
|
||||
#define DOUBLE_SCIENTIFIC_PRECISION -4
|
||||
#define DOUBLE_SIGN_BIT 0x8000000000000000ULL
|
||||
|
||||
/* Print flag definitions */
|
||||
#define PFL_ALWAYS_PRINT_SIGN 0x00000001
|
||||
#define PFL_SPACE_FOR_PLUS 0x00000002
|
||||
#define PFL_LEFT_JUSTIFIED 0x00000004
|
||||
#define PFL_LEADING_ZEROES 0x00000008
|
||||
#define PFL_LONG_INTEGER 0x00000010
|
||||
#define PFL_LONG_DOUBLE 0x00000020
|
||||
#define PFL_WIDE_CHARACTER 0x00000040
|
||||
#define PFL_SHORT_VALUE 0x00000080
|
||||
#define PFL_UNSIGNED 0x00000100
|
||||
#define PFL_UPPERCASE 0x00000200
|
||||
#define PFL_PRINT_RADIX 0x00000400
|
||||
#define PFL_FLOAT_FORMAT 0x00000800
|
||||
#define PFL_SCI_FORMAT 0x00001000
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
#define PFL_ALWAYS_PRINT_SIGN 0x00000001
|
||||
#define PFL_SPACE_FOR_PLUS 0x00000002
|
||||
#define PFL_LEFT_JUSTIFIED 0x00000004
|
||||
#define PFL_LEADING_ZEROES 0x00000008
|
||||
#define PFL_LONG_INTEGER 0x00000010
|
||||
#define PFL_LONG_DOUBLE 0x00000020
|
||||
#define PFL_WIDE_CHARACTER 0x00000040
|
||||
#define PFL_SHORT_VALUE 0x00000080
|
||||
#define PFL_UNSIGNED 0x00000100
|
||||
#define PFL_UPPERCASE 0x00000200
|
||||
#define PFL_PRINT_RADIX 0x00000400
|
||||
#define PFL_FLOAT_FORMAT 0x00000800
|
||||
#define PFL_SCI_FORMAT 0x00001000
|
||||
#define PFL_DIGIT_PRECISION 0x00002000
|
||||
#define PFL_THOUSANDS_GROUPING 0x00004000
|
||||
|
||||
/* Red-black tree definitions */
|
||||
#define RTL_BALANCED_NODE_RESERVED_PARENT_MASK 3
|
||||
#define RTL_BALANCED_NODE_COLOR_MASK 1
|
||||
|
||||
/* Cryptographic related definitions */
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
/* Time related definitions */
|
||||
#define TIME_SECONDS_PER_MINUTE 60
|
||||
#define TIME_SECONDS_PER_HOUR 3600
|
||||
#define TIME_SECONDS_PER_DAY 86400
|
||||
#define TIME_TICKS_PER_SECOND 10000000
|
||||
#define TIME_TICKS_PER_MILLISECOND 10000
|
||||
#define TIME_SECONDS_PER_MINUTE 60
|
||||
#define TIME_SECONDS_PER_HOUR 3600
|
||||
#define TIME_SECONDS_PER_DAY 86400
|
||||
#define TIME_TICKS_PER_SECOND 10000000
|
||||
#define TIME_TICKS_PER_MILLISECOND 10000
|
||||
|
||||
|
||||
/* C/C++ specific code */
|
||||
@@ -68,6 +72,13 @@
|
||||
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
|
||||
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
|
||||
|
||||
/* Red-black tree node color enumeration list */
|
||||
typedef enum _RTL_BALANCED_NODE_COLOR
|
||||
{
|
||||
NodeBlack,
|
||||
NodeRed
|
||||
} RTL_BALANCED_NODE_COLOR, *PRTL_BALANCED_NODE_COLOR;
|
||||
|
||||
/* Variable types enumeration list */
|
||||
typedef enum _RTL_VARIABLE_TYPE
|
||||
{
|
||||
@@ -84,6 +95,26 @@ typedef enum _RTL_VARIABLE_TYPE
|
||||
TypeWideString
|
||||
} RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||
|
||||
/* Runtime Library red-black tree balanced node structure definition */
|
||||
typedef struct _RTL_BALANCED_NODE
|
||||
{
|
||||
union
|
||||
{
|
||||
PRTL_BALANCED_NODE Children[2];
|
||||
struct
|
||||
{
|
||||
PRTL_BALANCED_NODE Left;
|
||||
PRTL_BALANCED_NODE Right;
|
||||
};
|
||||
};
|
||||
union
|
||||
{
|
||||
UCHAR Red:1;
|
||||
UCHAR Balance:2;
|
||||
ULONG_PTR ParentValue;
|
||||
};
|
||||
} RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
|
||||
|
||||
/* Bit Map structure definition */
|
||||
typedef struct _RTL_BITMAP
|
||||
{
|
||||
@@ -110,12 +141,19 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
|
||||
LONG Flags;
|
||||
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||
|
||||
/* Runtime Library red-black tree structure definition */
|
||||
typedef struct _RTL_RB_TREE
|
||||
{
|
||||
PRTL_BALANCED_NODE Root;
|
||||
PRTL_BALANCED_NODE Min;
|
||||
} RTL_RB_TREE, *PRTL_RB_TREE;
|
||||
|
||||
/* Runtime Library SHA-1 context structure definition */
|
||||
typedef struct _RTL_SHA1_CONTEXT
|
||||
{
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
ULONG State[5];
|
||||
ULONG Count[2];
|
||||
UCHAR Buffer[SHA1_BLOCK_SIZE];
|
||||
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
|
||||
|
||||
/* Runtime time fields structure definition */
|
||||
|
||||
@@ -57,6 +57,7 @@ typedef enum _MMPFN_CACHE_ATTRIBUTE MMPFN_CACHE_ATTRIBUTE, *PMMPFN_CACHE_ATTRIBU
|
||||
typedef enum _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
|
||||
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
|
||||
typedef enum _MODE MODE, *PMODE;
|
||||
typedef enum _RTL_BALANCED_NODE_COLOR RTL_BALANCED_NODE_COLOR, *PRTL_BALANCED_NODE_COLOR;
|
||||
typedef enum _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
|
||||
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
|
||||
typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_TYPE;
|
||||
@@ -327,9 +328,11 @@ typedef struct _POOL_TRACKING_BIG_ALLOCATIONS POOL_TRACKING_BIG_ALLOCATIONS, *PP
|
||||
typedef struct _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
|
||||
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
|
||||
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE;
|
||||
typedef struct _RTL_BALANCED_NODE RTL_BALANCED_NODE, *PRTL_BALANCED_NODE;
|
||||
typedef struct _RTL_BITMAP RTL_BITMAP, *PRTL_BITMAP;
|
||||
typedef struct _RTL_PRINT_CONTEXT RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT;
|
||||
typedef struct _RTL_PRINT_FORMAT_PROPERTIES RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
|
||||
typedef struct _RTL_RB_TREE RTL_RB_TREE, *PRTL_RB_TREE;
|
||||
typedef struct _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;
|
||||
typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;
|
||||
|
||||
@@ -88,6 +88,7 @@ list(APPEND XTOSKRNL_SOURCE
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/rbtree.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
|
||||
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
|
||||
|
||||
@@ -463,7 +463,7 @@ ApEnterLongMode:
|
||||
movl %edi, %edi
|
||||
|
||||
/* Load dedicated Stack for AP */
|
||||
movq PROCESSOR_START_BLOCK_Stack(%rdi), %rsp
|
||||
movq PROCESSOR_START_BLOCK_InitialStack(%rdi), %rsp
|
||||
|
||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||
movq %rdi, %rcx
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
AR::CpuFunctions::ClearInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
* @param Registers
|
||||
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
|
||||
*
|
||||
* @return TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
* @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
{
|
||||
UINT32 MaxLeaf;
|
||||
|
||||
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::FlushTlb(VOID)
|
||||
AR::CpuFunctions::FlushTlb(VOID)
|
||||
{
|
||||
/* Flush the TLB by resetting the CR3 */
|
||||
WriteControlRegister(3, ReadControlRegister(3));
|
||||
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::GetCpuFlags(VOID)
|
||||
AR::CpuFunctions::GetCpuFlags(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
|
||||
XTASSEMBLY
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::GetStackPointer(VOID)
|
||||
AR::CpuFunctions::GetStackPointer(VOID)
|
||||
{
|
||||
/* Get current stack pointer */
|
||||
__asm__ volatile("movq %%rsp, %%rax\n"
|
||||
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::Halt(VOID)
|
||||
AR::CpuFunctions::Halt(VOID)
|
||||
{
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
AR::CpuFunctions::InterruptsEnabled(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address)
|
||||
AR::CpuFunctions::InvalidateTlbEntry(IN PVOID Address)
|
||||
{
|
||||
__asm__ volatile("invlpg (%0)"
|
||||
:
|
||||
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lgdt %0"
|
||||
:
|
||||
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lidt %0"
|
||||
:
|
||||
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
{
|
||||
__asm__ volatile("lldtw %0"
|
||||
:
|
||||
@@ -251,7 +251,7 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source)
|
||||
AR::CpuFunctions::LoadMxcsrRegister(IN ULONG Source)
|
||||
{
|
||||
__asm__ volatile("ldmxcsr %0"
|
||||
:
|
||||
@@ -273,7 +273,7 @@ AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
AR::CpuFunctions::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
{
|
||||
switch(Segment)
|
||||
@@ -335,7 +335,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
AR::CpuFunctions::LoadTaskRegister(USHORT Source)
|
||||
{
|
||||
__asm__ volatile("ltr %0"
|
||||
:
|
||||
@@ -351,7 +351,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::MemoryBarrier(VOID)
|
||||
AR::CpuFunctions::MemoryBarrier(VOID)
|
||||
{
|
||||
LONG Barrier;
|
||||
__asm__ volatile("lock; orl $0, %0;"
|
||||
@@ -365,13 +365,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
|
||||
* @param ControlRegister
|
||||
* Supplies a number of a control register which controls the general behavior of a CPU.
|
||||
*
|
||||
* @return The value stored in the control register.
|
||||
* @return This routine returns the value stored in the control register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -429,13 +429,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
* @param DebugRegister
|
||||
* Supplies a number of a debug register to read from.
|
||||
*
|
||||
* @return The value stored in the specified debug register.
|
||||
* @return This routine returns the value stored in the specified debug register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -498,13 +498,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
* @param Offset
|
||||
* Specifies the offset from the beginning of GS segment.
|
||||
*
|
||||
* @return Returns the value read from the specified memory location relative to GS segment.
|
||||
* @return This routine returns the value read from the specified memory location relative to GS segment.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadGSQuadWord(ULONG Offset)
|
||||
AR::CpuFunctions::ReadGSQuadWord(ULONG Offset)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -527,7 +527,7 @@ AR::CpuFunc::ReadGSQuadWord(ULONG Offset)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
|
||||
{
|
||||
ULONG Low, High;
|
||||
|
||||
@@ -548,7 +548,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
*/
|
||||
XTCDECL
|
||||
UINT
|
||||
AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
AR::CpuFunctions::ReadMxCsrRegister(VOID)
|
||||
{
|
||||
return __builtin_ia32_stmxcsr();
|
||||
}
|
||||
@@ -562,7 +562,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
AR::CpuFunctions::ReadTimeStampCounter(VOID)
|
||||
{
|
||||
ULONGLONG Low, High;
|
||||
|
||||
@@ -585,7 +585,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
AR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
{
|
||||
ULONG Low, High;
|
||||
|
||||
@@ -609,7 +609,7 @@ AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
AR::CpuFunctions::ReadWriteBarrier(VOID)
|
||||
{
|
||||
__asm__ volatile(""
|
||||
:
|
||||
@@ -626,7 +626,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
AR::CpuFunctions::SetInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
@@ -643,7 +643,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sgdt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -663,7 +663,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sidt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -683,7 +683,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sldt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -706,8 +706,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -753,7 +753,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("str %0"
|
||||
: "=m" (*(PULONG)Destination)
|
||||
@@ -776,8 +776,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified control register */
|
||||
switch(ControlRegister)
|
||||
@@ -835,8 +835,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified debug register */
|
||||
switch(DebugRegister)
|
||||
@@ -912,7 +912,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
{
|
||||
__asm__ volatile("push %0\n"
|
||||
"popf"
|
||||
@@ -935,8 +935,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
ULONG Low = Value & 0xFFFFFFFF;
|
||||
ULONG High = Value >> 32;
|
||||
@@ -957,7 +957,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::YieldProcessor(VOID)
|
||||
AR::CpuFunctions::YieldProcessor(VOID)
|
||||
{
|
||||
__asm__ volatile("pause"
|
||||
:
|
||||
|
||||
@@ -10,25 +10,25 @@
|
||||
|
||||
|
||||
/* Initial kernel boot stack */
|
||||
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial kernel fault stack */
|
||||
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial GDT */
|
||||
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {};
|
||||
KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
|
||||
|
||||
/* Initial IDT */
|
||||
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {};
|
||||
KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
|
||||
|
||||
/* Initial Processor Block */
|
||||
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
KTSS AR::ProcessorSupport::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
AR::ProcessorSupport::GetBootStack(VOID)
|
||||
{
|
||||
/* Return base address of kernel boot stack */
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
@@ -26,9 +26,9 @@ AR::ProcSup::GetBootStack(VOID)
|
||||
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
{
|
||||
/* Get trampoline information */
|
||||
switch(TrampolineType)
|
||||
@@ -63,7 +63,7 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessor(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessor(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
@@ -75,7 +75,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -87,7 +87,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -137,7 +137,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
|
||||
{
|
||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
@@ -149,13 +149,13 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get maximum CPUID standard leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Get maximum CPUID extended leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check if CPU supports standard features leaf */
|
||||
@@ -164,7 +164,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||
@@ -208,7 +208,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard7 features in processor control block */
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||
@@ -226,7 +226,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU power management features in processor control block */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||
@@ -238,7 +238,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU extended features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU extended features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||
@@ -259,7 +259,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU advanced power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU advanced power management features in processor control block */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||
@@ -278,7 +278,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
/* Initialize GDT entries */
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
|
||||
@@ -307,7 +307,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
UINT Vector;
|
||||
|
||||
@@ -355,7 +355,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
@@ -401,16 +401,16 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
|
||||
/* Set GS base */
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
|
||||
|
||||
/* Initialize processor registers */
|
||||
InitializeProcessorRegisters();
|
||||
@@ -440,11 +440,11 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
AR::ProcessorSupport::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;
|
||||
@@ -490,50 +490,51 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
ULONGLONG PatAttributes;
|
||||
|
||||
/* Enable FXSAVE restore */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_FXSR);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_FXSR);
|
||||
|
||||
/* Enable XMMI exceptions */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_XMMEXCPT);
|
||||
|
||||
/* Set debugger extension */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_DE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_DE);
|
||||
|
||||
/* Enable large pages */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PSE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PSE);
|
||||
|
||||
/* Enable write-protection */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);
|
||||
|
||||
/* Set alignment mask */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_AM);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_AM);
|
||||
|
||||
/* Disable FPU monitoring */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_MP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_MP);
|
||||
|
||||
/* Disable x87 FPU exceptions */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) & ~CR0_NE);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) & ~CR0_NE);
|
||||
|
||||
/* Flush the TLB */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Initialize system call MSRs */
|
||||
AR::Traps::InitializeSystemCallMsrs();
|
||||
|
||||
/* Enable No-Execute (NXE) in EFER MSR */
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_NXE);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER,
|
||||
CpuFunctions::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);
|
||||
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
|
||||
|
||||
/* Initialize MXCSR register */
|
||||
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
AR::CpuFunctions::LoadMxcsrRegister(INITIAL_MXCSR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,13 +564,13 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -631,15 +632,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
AR::ProcessorSupport::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -657,10 +658,10 @@ AR::ProcSup::InitializeSegments(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
/* Fill TSS with zeroes */
|
||||
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
|
||||
@@ -703,13 +704,13 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
AR::ProcessorSupport::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;
|
||||
@@ -769,9 +770,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
|
||||
@@ -815,13 +816,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
|
||||
|
||||
@@ -26,8 +26,8 @@ AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
|
||||
/* Check if the interrupt has a handler registered */
|
||||
if(Handler != NULLPTR)
|
||||
@@ -672,13 +672,13 @@ VOID
|
||||
AR::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);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
|
||||
CpuFunctions::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);
|
||||
CpuFunctions::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunctions::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -311,7 +311,7 @@ ApEnterProtectedMode:
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Load dedicated Stack for AP */
|
||||
movl PROCESSOR_START_BLOCK_Stack(%edi), %esp
|
||||
movl PROCESSOR_START_BLOCK_InitialStack(%edi), %esp
|
||||
|
||||
/* Save the pointer to PROCESSOR_START_BLOCK */
|
||||
movl %edi, %ecx
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
AR::CpuFunctions::ClearInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("cli");
|
||||
}
|
||||
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
|
||||
* @param Registers
|
||||
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID.
|
||||
*
|
||||
* @return TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
* @return This routine returns TRUE if CPUID function could be executed, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
{
|
||||
UINT32 MaxLeaf;
|
||||
|
||||
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::FlushTlb(VOID)
|
||||
AR::CpuFunctions::FlushTlb(VOID)
|
||||
{
|
||||
/* Flush the TLB by resetting the CR3 */
|
||||
WriteControlRegister(3, ReadControlRegister(3));
|
||||
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::GetCpuFlags(VOID)
|
||||
AR::CpuFunctions::GetCpuFlags(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
|
||||
XTASSEMBLY
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::GetStackPointer(VOID)
|
||||
AR::CpuFunctions::GetStackPointer(VOID)
|
||||
{
|
||||
/* Get current stack pointer */
|
||||
__asm__ volatile("mov %%esp, %%eax\n"
|
||||
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::Halt(VOID)
|
||||
AR::CpuFunctions::Halt(VOID)
|
||||
{
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
AR::CpuFunctions::InterruptsEnabled(VOID)
|
||||
{
|
||||
ULONG_PTR Flags;
|
||||
|
||||
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::InvalidateTlbEntry(PVOID Address)
|
||||
AR::CpuFunctions::InvalidateTlbEntry(PVOID Address)
|
||||
{
|
||||
__asm__ volatile("invlpg (%0)"
|
||||
:
|
||||
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(PVOID Address)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lgdt %0"
|
||||
:
|
||||
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
{
|
||||
__asm__ volatile("lidt %0"
|
||||
:
|
||||
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
{
|
||||
__asm__ volatile("lldtw %0"
|
||||
:
|
||||
@@ -254,8 +254,8 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
AR::CpuFunctions::LoadSegment(IN USHORT Segment,
|
||||
IN ULONG Source)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -316,7 +316,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
AR::CpuFunctions::LoadTaskRegister(USHORT Source)
|
||||
{
|
||||
__asm__ volatile("ltr %0"
|
||||
:
|
||||
@@ -332,7 +332,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::MemoryBarrier(VOID)
|
||||
AR::CpuFunctions::MemoryBarrier(VOID)
|
||||
{
|
||||
LONG Barrier;
|
||||
__asm__ volatile("xchg %%eax, %0"
|
||||
@@ -347,13 +347,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
|
||||
* @param ControlRegister
|
||||
* Supplies a number of a control register which controls the general behavior of a CPU.
|
||||
*
|
||||
* @return The value stored in the control register.
|
||||
* @return This routine returns the value stored in the control register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -404,13 +404,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
|
||||
* @param DebugRegister
|
||||
* Supplies a number of a debug register to read from.
|
||||
*
|
||||
* @return The value stored in the specified debug register.
|
||||
* @return This routine returns the value stored in the specified debug register.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG_PTR
|
||||
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
{
|
||||
ULONG_PTR Value;
|
||||
|
||||
@@ -473,13 +473,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
|
||||
* @param Offset
|
||||
* Specifies the offset from the beginning of FS segment.
|
||||
*
|
||||
* @return Returns the value read from the specified memory location relative to FS segment.
|
||||
* @return This routine returns the value read from the specified memory location relative to FS segment.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
ULONG
|
||||
AR::CpuFunc::ReadFSDualWord(ULONG Offset)
|
||||
AR::CpuFunctions::ReadFSDualWord(ULONG Offset)
|
||||
{
|
||||
ULONG Value;
|
||||
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
|
||||
@@ -500,7 +500,7 @@ AR::CpuFunc::ReadFSDualWord(ULONG Offset)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -519,7 +519,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
|
||||
*/
|
||||
XTCDECL
|
||||
UINT
|
||||
AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
AR::CpuFunctions::ReadMxCsrRegister(VOID)
|
||||
{
|
||||
return __builtin_ia32_stmxcsr();
|
||||
}
|
||||
@@ -533,7 +533,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
AR::CpuFunctions::ReadTimeStampCounter(VOID)
|
||||
{
|
||||
ULONGLONG Value;
|
||||
|
||||
@@ -555,7 +555,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
ULONGLONG
|
||||
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
AR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
{
|
||||
ULONG Low, High;
|
||||
|
||||
@@ -579,7 +579,7 @@ AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
AR::CpuFunctions::ReadWriteBarrier(VOID)
|
||||
{
|
||||
__asm__ volatile(""
|
||||
:
|
||||
@@ -596,7 +596,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
AR::CpuFunctions::SetInterruptFlag(VOID)
|
||||
{
|
||||
__asm__ volatile("sti");
|
||||
}
|
||||
@@ -613,7 +613,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sgdt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -633,7 +633,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sidt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -653,7 +653,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("sldt %0"
|
||||
: "=m" (*(PSHORT)Destination)
|
||||
@@ -676,8 +676,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreSegment(IN USHORT Segment,
|
||||
OUT PVOID Destination)
|
||||
{
|
||||
switch(Segment)
|
||||
{
|
||||
@@ -723,7 +723,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
|
||||
{
|
||||
__asm__ volatile("str %0"
|
||||
: "=m" (*(PULONG)Destination)
|
||||
@@ -746,8 +746,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified control register */
|
||||
switch(ControlRegister)
|
||||
@@ -798,8 +798,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
IN UINT_PTR Value)
|
||||
{
|
||||
/* Write a value into specified debug register */
|
||||
switch(DebugRegister)
|
||||
@@ -867,7 +867,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
{
|
||||
__asm__ volatile("push %0\n"
|
||||
"popf"
|
||||
@@ -890,8 +890,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
|
||||
IN ULONGLONG Value)
|
||||
{
|
||||
__asm__ volatile("wrmsr"
|
||||
:
|
||||
@@ -908,7 +908,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
AR::CpuFunc::YieldProcessor(VOID)
|
||||
AR::CpuFunctions::YieldProcessor(VOID)
|
||||
{
|
||||
__asm__ volatile("pause"
|
||||
:
|
||||
|
||||
@@ -10,31 +10,31 @@
|
||||
|
||||
|
||||
/* Initial kernel boot stack */
|
||||
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Double Fault gate */
|
||||
UCHAR AR::ProcSup::DoubleFaultTss[KTSS_IO_MAPS];
|
||||
UCHAR AR::ProcessorSupport::DoubleFaultTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Initial kernel fault stack */
|
||||
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* Initial GDT */
|
||||
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {};
|
||||
KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
|
||||
|
||||
/* Initial IDT */
|
||||
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {};
|
||||
KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
|
||||
|
||||
/* Initial Processor Block */
|
||||
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock;
|
||||
KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
|
||||
|
||||
/* Initial TSS */
|
||||
KTSS AR::ProcSup::InitialTss;
|
||||
KTSS AR::ProcessorSupport::InitialTss;
|
||||
|
||||
/* Initial kernel NMI stack */
|
||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||
|
||||
/* NMI task gate */
|
||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
UCHAR AR::ProcessorSupport::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||
|
||||
/* Unhandled interrupt routine */
|
||||
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*/
|
||||
XTAPI
|
||||
PVOID
|
||||
AR::ProcSup::GetBootStack(VOID)
|
||||
AR::ProcessorSupport::GetBootStack(VOID)
|
||||
{
|
||||
/* Return base address of kernel boot stack */
|
||||
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
|
||||
@@ -26,9 +26,9 @@ AR::ProcSup::GetBootStack(VOID)
|
||||
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
OUT PVOID *TrampolineCode,
|
||||
OUT PULONG_PTR TrampolineSize)
|
||||
{
|
||||
/* Get trampoline information */
|
||||
switch(TrampolineType)
|
||||
@@ -56,7 +56,7 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessor(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessor(VOID)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
CPUID_REGISTERS CpuRegisters;
|
||||
@@ -68,7 +68,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU vendor by issueing CPUID instruction */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU vendor in processor control block */
|
||||
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
|
||||
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
/* Get CPU standard features */
|
||||
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU signature in processor control block */
|
||||
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
|
||||
@@ -130,7 +130,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
|
||||
{
|
||||
ULONG MaxExtendedLeaf, MaxStandardLeaf;
|
||||
PKPROCESSOR_CONTROL_BLOCK Prcb;
|
||||
@@ -142,13 +142,13 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get maximum CPUID standard leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Get maximum CPUID extended leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxExtendedLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check if CPU supports standard features leaf */
|
||||
@@ -157,7 +157,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
|
||||
@@ -201,7 +201,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU standard features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU standard7 features in processor control block */
|
||||
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE;
|
||||
@@ -219,7 +219,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU power management features in processor control block */
|
||||
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
|
||||
@@ -231,7 +231,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU extended features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU extended features in processor control block */
|
||||
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM;
|
||||
@@ -252,7 +252,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
/* Get CPU advanced power management features */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Store CPU advanced power management features in processor control block */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
|
||||
@@ -271,7 +271,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
/* Initialize GDT entries */
|
||||
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
|
||||
@@ -302,7 +302,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
{
|
||||
UINT Vector;
|
||||
|
||||
@@ -351,7 +351,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
{
|
||||
KDESCRIPTOR GdtDescriptor, IdtDescriptor;
|
||||
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
|
||||
@@ -397,9 +397,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
|
||||
|
||||
/* Load GDT, IDT and TSS */
|
||||
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
|
||||
AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
|
||||
|
||||
/* Initialize segment registers */
|
||||
InitializeSegments();
|
||||
@@ -432,11 +432,11 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PKGDTENTRY Gdt,
|
||||
IN PKIDTENTRY Idt,
|
||||
IN PKTSS Tss,
|
||||
IN PVOID DpcStack)
|
||||
AR::ProcessorSupport::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;
|
||||
@@ -478,13 +478,13 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
|
||||
{
|
||||
/* Clear EFLAGS register */
|
||||
AR::CpuFunc::WriteEflagsRegister(0);
|
||||
AR::CpuFunctions::WriteEflagsRegister(0);
|
||||
|
||||
/* Enable write-protection */
|
||||
AR::CpuFunc::WriteControlRegister(0, AR::CpuFunc::ReadControlRegister(0) | CR0_WP);
|
||||
AR::CpuFunctions::WriteControlRegister(0, AR::CpuFunctions::ReadControlRegister(0) | CR0_WP);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -514,13 +514,13 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
OUT PKGDTENTRY *Gdt,
|
||||
OUT PKTSS *Tss,
|
||||
OUT PKPROCESSOR_BLOCK *ProcessorBlock,
|
||||
OUT PVOID *KernelBootStack,
|
||||
OUT PVOID *KernelFaultStack,
|
||||
OUT PVOID *KernelNmiStack)
|
||||
{
|
||||
UINT_PTR Address;
|
||||
|
||||
@@ -582,15 +582,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeSegments(VOID)
|
||||
AR::ProcessorSupport::InitializeSegments(VOID)
|
||||
{
|
||||
/* Initialize segments */
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0);
|
||||
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_GS, 0);
|
||||
AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -605,10 +605,10 @@ AR::ProcSup::InitializeSegments(VOID)
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelBootStack,
|
||||
IN PVOID KernelFaultStack,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TssEntry;
|
||||
|
||||
@@ -644,7 +644,7 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
ProcessorBlock->TssBase->Flags = 0;
|
||||
|
||||
/* Set CR3, LDT and SS */
|
||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
ProcessorBlock->TssBase->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
ProcessorBlock->TssBase->LDT = 0;
|
||||
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
|
||||
|
||||
@@ -665,8 +665,8 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
AR::ProcessorSupport::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelFaultStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -683,7 +683,7 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];
|
||||
@@ -736,13 +736,13 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base,
|
||||
IN ULONG Limit,
|
||||
IN UCHAR Type,
|
||||
IN UCHAR Dpl,
|
||||
IN UCHAR SegmentMode)
|
||||
AR::ProcessorSupport::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;
|
||||
@@ -800,9 +800,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
IN USHORT Selector,
|
||||
IN ULONG_PTR Base)
|
||||
{
|
||||
PKGDTENTRY GdtEntry;
|
||||
|
||||
@@ -845,13 +845,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
IN USHORT Vector,
|
||||
IN PVOID Handler,
|
||||
IN USHORT Selector,
|
||||
IN USHORT Ist,
|
||||
IN USHORT Dpl,
|
||||
IN USHORT Type)
|
||||
{
|
||||
/* Set the handler's address */
|
||||
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
|
||||
@@ -879,8 +879,8 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelNmiStack)
|
||||
AR::ProcessorSupport::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
|
||||
IN PVOID KernelNmiStack)
|
||||
{
|
||||
PKGDTENTRY TaskGateEntry, TssEntry;
|
||||
PKTSS Tss;
|
||||
@@ -897,7 +897,7 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
|
||||
Tss->IoMapBase = sizeof(KTSS);
|
||||
Tss->Flags = 0;
|
||||
Tss->LDT = 0;
|
||||
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
Tss->Esp = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
|
||||
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];
|
||||
|
||||
@@ -26,8 +26,8 @@ AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
PINTERRUPT_HANDLER Handler;
|
||||
|
||||
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||
|
||||
/* Check if the interrupt has a handler registered */
|
||||
if(Handler != NULLPTR)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
BOOLEAN
|
||||
@@ -65,7 +65,7 @@ EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
@@ -82,7 +82,7 @@ EX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
@@ -100,7 +100,7 @@ EX::Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
@@ -117,7 +117,7 @@ EX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
@@ -168,7 +168,7 @@ EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
VOID
|
||||
|
||||
@@ -50,7 +50,7 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
|
||||
* @param Rsdp
|
||||
* Supplies a pointer to the memory area, where RSDP virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -72,7 +72,7 @@ HL::Acpi::GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -148,7 +148,7 @@ HL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)
|
||||
/**
|
||||
* Performs an initialization of the ACPI subsystem.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -185,7 +185,7 @@ HL::Acpi::InitializeAcpi(VOID)
|
||||
/**
|
||||
* Initializes the kernel's local ACPI cache storage.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -220,7 +220,7 @@ HL::Acpi::InitializeAcpiCache(VOID)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -326,7 +326,7 @@ HL::Acpi::InitializeAcpiSystemDescriptionTable(OUT PACPI_DESCRIPTION_HEADER *Acp
|
||||
/**
|
||||
* Initializes System Information structure based on the ACPI provided data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -425,7 +425,7 @@ HL::Acpi::InitializeAcpiSystemInformation(VOID)
|
||||
/**
|
||||
* Initializes ACPI System Information data structure based on the size of available ACPI data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -521,7 +521,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
|
||||
/**
|
||||
* Initializes the ACPI Timer.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -568,7 +568,7 @@ HL::Acpi::InitializeAcpiTimer(VOID)
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -625,7 +625,7 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
|
||||
* @param AcpiTable
|
||||
* Supplies a pointer to memory area where ACPI table virtual address will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -36,7 +36,7 @@ HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
|
||||
KE::RunLevel::RaiseRunLevel(RunLevel);
|
||||
|
||||
/* Enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +58,7 @@ HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
|
||||
IN KRUNLEVEL OldRunLevel)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* End system interrupt */
|
||||
EndSystemInterrupt(TrapFrame, OldRunLevel);
|
||||
@@ -125,7 +125,7 @@ HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Print debug message and raise kernel panic */
|
||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector);
|
||||
@@ -205,13 +205,13 @@ HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
AMD64_INTERRUPT_GATE);
|
||||
AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
AMD64_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ KRUNLEVEL
|
||||
HL::RunLevel::GetRunLevel(VOID)
|
||||
{
|
||||
/* Read current run level */
|
||||
return (KRUNLEVEL)AR::CpuFunc::ReadControlRegister(8);
|
||||
return (KRUNLEVEL)AR::CpuFunctions::ReadControlRegister(8);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ VOID
|
||||
HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
|
||||
{
|
||||
/* Set new run level */
|
||||
AR::CpuFunc::WriteControlRegister(8, RunLevel);
|
||||
AR::CpuFunctions::WriteControlRegister(8, RunLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* @param Poll
|
||||
* Indicates whether to only poll, not reading the data.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -98,7 +98,7 @@ HL::ComPort::ReadComPort(IN PCPPORT Port,
|
||||
* @param Byte
|
||||
* Value expected from the port.
|
||||
*
|
||||
* @return Byte read from COM port.
|
||||
* @return This routine returns a byte read from COM port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -144,7 +144,7 @@ HL::ComPort::ReadComPortLsr(IN PCPPORT Port,
|
||||
* @param BaudRate
|
||||
* Supplies an optional port baud rate.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -240,7 +240,7 @@ HL::ComPort::InitializeComPort(IN OUT PCPPORT Port,
|
||||
* @param Byte
|
||||
* Data to be written.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -379,7 +379,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
|
||||
/**
|
||||
* Enables the Shadow Buffer (Double Buffering) for high-performance rendering.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -452,7 +452,7 @@ HL::FrameBuffer::GetFrameBufferResolution(OUT PULONG Width,
|
||||
* @param Color
|
||||
* Specifies the color in (A)RGB format.
|
||||
*
|
||||
* @return Returns the color in FrameBuffer format.
|
||||
* @return This routine returns the color in FrameBuffer format.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -476,7 +476,7 @@ HL::FrameBuffer::GetRGBColor(IN ULONG Color)
|
||||
/**
|
||||
* Initializes frame buffer display.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
|
||||
* @param Port
|
||||
* Specifies the address to read from, in the range of 0-0xFFFF.
|
||||
*
|
||||
* @return The value read from the port.
|
||||
* @return This routine returns the value read from the port.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,7 @@ HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
|
||||
KE::RunLevel::RaiseRunLevel(RunLevel);
|
||||
|
||||
/* Enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
|
||||
IN KRUNLEVEL OldRunLevel)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* End system interrupt */
|
||||
EndSystemInterrupt(TrapFrame, OldRunLevel);
|
||||
@@ -126,7 +126,7 @@ HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Print debug message and raise kernel panic */
|
||||
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector);
|
||||
@@ -204,13 +204,13 @@ HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
|
||||
/* Update interrupt handler */
|
||||
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
I686_INTERRUPT_GATE);
|
||||
AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,
|
||||
Vector,
|
||||
Handler,
|
||||
KGDT_R0_CODE,
|
||||
0,
|
||||
KIDT_ACCESS_RING0,
|
||||
I686_INTERRUPT_GATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,7 +99,7 @@ HL::Cpu::StartAllProcessors(VOID)
|
||||
}
|
||||
|
||||
/* Get trampoline information */
|
||||
AR::ProcSup::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);
|
||||
AR::ProcessorSupport::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);
|
||||
|
||||
/* Verify trampoline information */
|
||||
if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0)
|
||||
@@ -161,8 +161,8 @@ HL::Cpu::StartAllProcessors(VOID)
|
||||
}
|
||||
|
||||
/* Get ProcessorBlock and Stack address */
|
||||
AR::ProcSup::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,
|
||||
&StartBlock->Stack, NULLPTR, NULLPTR);
|
||||
AR::ProcessorSupport::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,
|
||||
&StartBlock->Stack, NULLPTR, NULLPTR);
|
||||
|
||||
/* Set processor number directly in the processor block */
|
||||
ProcessorBlock->CpuNumber = CpuNumber;
|
||||
@@ -171,14 +171,15 @@ HL::Cpu::StartAllProcessors(VOID)
|
||||
KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock);
|
||||
|
||||
/* Initialize processor start block */
|
||||
StartBlock->Cr3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
StartBlock->Cr4 = AR::CpuFunc::ReadControlRegister(4);
|
||||
StartBlock->Cr3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
StartBlock->Cr4 = AR::CpuFunctions::ReadControlRegister(4);
|
||||
StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor;
|
||||
StartBlock->InitialStack = (PVOID)((ULONG_PTR)StartBlock->Stack - KTHREAD_STACK_OFFSET);
|
||||
StartBlock->ProcessorStructures = CpuStructures;
|
||||
StartBlock->Started = FALSE;
|
||||
|
||||
/* Memory barrier */
|
||||
AR::CpuFunc::MemoryBarrier();
|
||||
AR::CpuFunctions::MemoryBarrier();
|
||||
|
||||
/* Send INIT IPI and wait for 10ms */
|
||||
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, 0, APIC_DM_INIT, APIC_DSH_Destination, APIC_TGM_EDGE);
|
||||
@@ -196,7 +197,7 @@ HL::Cpu::StartAllProcessors(VOID)
|
||||
while(!StartBlock->Started && Timeout < 100000)
|
||||
{
|
||||
/* Yield processor and wait for 10us */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
HL::Timer::StallExecution(10);
|
||||
Timeout++;
|
||||
}
|
||||
|
||||
@@ -13,13 +13,16 @@
|
||||
/**
|
||||
* Allocates, maps and commits a requested system interrupt level internally.
|
||||
*
|
||||
* @param Irq
|
||||
* Supplies the hardware IRQ line number to be allocated and mapped.
|
||||
*
|
||||
* @param RunLevel
|
||||
* Supplies the actual system run level to allocate.
|
||||
*
|
||||
* @param Vector
|
||||
* Supplies the interrupt handler vector assigned to process requests originating on the line.
|
||||
*
|
||||
* @return This routine returns the configured target vector.
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -136,7 +139,7 @@ HL::Pic::ClearApicErrors(VOID)
|
||||
/**
|
||||
* Searches the ACPI MADT tables for the I/O APIC controllers.
|
||||
*
|
||||
* @return This routine returns the status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -264,7 +267,7 @@ HL::Pic::GetCpuApicId(VOID)
|
||||
* @param EntryNumber
|
||||
* Supplies a pointer to the memory area where the entry number will be stored.
|
||||
*
|
||||
* @return This routine returns the status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -361,11 +364,11 @@ HL::Pic::InitializeApic(VOID)
|
||||
CpuNumber = KE::Processor::GetCurrentProcessorNumber();
|
||||
|
||||
/* Enable the APIC */
|
||||
BaseRegister.LongLong = AR::CpuFunc::ReadModelSpecificRegister(APIC_LAPIC_MSR_BASE);
|
||||
BaseRegister.LongLong = AR::CpuFunctions::ReadModelSpecificRegister(APIC_LAPIC_MSR_BASE);
|
||||
BaseRegister.Enable = 1;
|
||||
BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC);
|
||||
BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0;
|
||||
AR::CpuFunc::WriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister(APIC_LAPIC_MSR_BASE, BaseRegister.LongLong);
|
||||
|
||||
/* Mask all interrupts by raising Task Priority Register (TPR) */
|
||||
WriteApicRegister(APIC_TPR, 0xFF);
|
||||
@@ -476,8 +479,8 @@ HL::Pic::InitializeIOApic(VOID)
|
||||
}
|
||||
|
||||
/* Perform a memory barrier */
|
||||
AR::CpuFunc::MemoryBarrier();
|
||||
AR::CpuFunc::ReadWriteBarrier();
|
||||
AR::CpuFunctions::MemoryBarrier();
|
||||
AR::CpuFunctions::ReadWriteBarrier();
|
||||
|
||||
/* Read the version register and calculate the maximum number of redirection entries */
|
||||
VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);
|
||||
@@ -636,7 +639,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Read from x2APIC MSR */
|
||||
return AR::CpuFunc::ReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register));
|
||||
return AR::CpuFunctions::ReadModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -779,10 +782,10 @@ HL::Pic::SendBroadcastIpi(IN ULONG Vector,
|
||||
HL::Acpi::GetSystemInformation(&SysInfo);
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
Interrupts = AR::CpuFunctions::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Iterate over all logical CPUs */
|
||||
for(Index = 0; Index < SysInfo->CpuCount; Index++)
|
||||
@@ -815,7 +818,7 @@ HL::Pic::SendBroadcastIpi(IN ULONG Vector,
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,10 +871,10 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
BOOLEAN Interrupts;
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
Interrupts = AR::CpuFunctions::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Check current APIC mode and destination */
|
||||
if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self)
|
||||
@@ -883,7 +886,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Check whether interrupts need to be re-enabled */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/* Nothing more to do */
|
||||
@@ -914,7 +917,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
|
||||
/* In xAPIC compatibility mode, write the command to the ICR registers */
|
||||
@@ -928,7 +931,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
while((ReadApicRegister((APIC_REGISTER)(APIC_IRR + (Vector / 32))) & (1UL << (Vector % 32))) == 0)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -937,7 +940,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1013,7 +1016,7 @@ HL::Pic::WriteApicRegister(IN APIC_REGISTER Register,
|
||||
if(ApicMode == APIC_MODE_X2APIC)
|
||||
{
|
||||
/* Write to x2APIC MSR */
|
||||
AR::CpuFunc::WriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value);
|
||||
AR::CpuFunctions::WriteModelSpecificRegister((ULONG)(APIC_X2APIC_MSR_BASE + Register), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* @param Time
|
||||
* Supplies a pointer to a structure to receive the system time.
|
||||
*
|
||||
* @return This routine returns the status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -58,7 +58,7 @@ HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
|
||||
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
|
||||
/* Latch the first sequential hardware time snapshot */
|
||||
@@ -81,7 +81,7 @@ HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
|
||||
while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
|
||||
{
|
||||
/* Yield the processor */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
|
||||
/* Latch the second sequential hardware time snapshot for verification */
|
||||
@@ -192,7 +192,7 @@ HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
|
||||
* @param Time
|
||||
* Supplies a pointer to a structure with populated data and time.
|
||||
*
|
||||
* @return This routine returns the status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
/**
|
||||
* Calibrates the Local APIC timer frequency.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -84,13 +84,13 @@ HL::Timer::CalibrateTscCounter(VOID)
|
||||
}
|
||||
|
||||
/* Latch the initial TSC value */
|
||||
InitialTickCount = AR::CpuFunc::ReadTimeStampCounterProcessor(&TscAux);
|
||||
InitialTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);
|
||||
|
||||
/* Stall CPU execution for exactly 10 milliseconds */
|
||||
StallExecution(10000);
|
||||
|
||||
/* Read current tick count from TSC */
|
||||
FinalTickCount = AR::CpuFunc::ReadTimeStampCounterProcessor(&TscAux);
|
||||
FinalTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);
|
||||
|
||||
/* Calculate the elapsed ticks over the 10ms window */
|
||||
return (FinalTickCount - InitialTickCount) * 100;
|
||||
@@ -104,6 +104,10 @@ HL::Timer::CalibrateTscCounter(VOID)
|
||||
*
|
||||
* @param HardwareDivider
|
||||
* Supplies the programmed threshold/divider for the interrupt generation.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -124,7 +128,7 @@ HL::Timer::ConfigureTimeIncrement(IN ULONGLONG BaseFrequency, IN ULONGLONG Hardw
|
||||
* Initializes the High Precision Event Timer (HPET) by discovering its ACPI configuration and mapping
|
||||
* its hardware registers into the kernel's virtual address space.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -388,7 +392,7 @@ HL::Timer::InitializeApicTimer(VOID)
|
||||
/**
|
||||
* Initializes the High Precision Event Timer (HPET) Timer.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -443,10 +447,41 @@ HL::Timer::InitializeHpetTimer(VOID)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the local hardware clock for the executing processor and registers
|
||||
* the necessary clock interrupt handlers.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Timer::InitializeLocalClock(VOID)
|
||||
{
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Check if LAPIC timer was selected as the system clock */
|
||||
if(ClockType == TimerLapic && TimerRoutines.InitializeClock != NULLPTR)
|
||||
{
|
||||
/* Proceed with system clock initialization */
|
||||
Status = TimerRoutines.InitializeClock();
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* CPU cannot operate without a functional system clock interrupt */
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Register the system clock interrupt handler */
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_CLOCK, HL::Timer::HandleClockInterrupt);
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_CLOCK_IPI, HL::Timer::HandleClockIpiInterrupt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the legacy Programmable Interval Timer (PIT).
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -911,7 +946,7 @@ HL::Timer::QueryPerformanceCounterTsc(VOID)
|
||||
ULONG TscAux;
|
||||
|
||||
/* Retrieve the timestamp */
|
||||
return AR::CpuFunc::ReadTimeStampCounterProcessor(&TscAux);
|
||||
return AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -941,7 +976,7 @@ HL::Timer::QueryTimerCapabilities(VOID)
|
||||
/* Query maximum standard CPUID leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
MaxStandardLeaf = CpuRegisters.Eax;
|
||||
|
||||
/* Check Always Running Timer - ART if leaf supported */
|
||||
@@ -950,7 +985,7 @@ HL::Timer::QueryTimerCapabilities(VOID)
|
||||
/* Query the Time Stamp Counter and Core Crystal Clock information CPUID leaf */
|
||||
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
|
||||
CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Verify Always Running Timer support */
|
||||
if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0)
|
||||
@@ -1047,10 +1082,10 @@ HL::Timer::SetClockRateApic(ULONG Rate)
|
||||
}
|
||||
|
||||
/* Check whether interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
Interrupts = AR::CpuFunctions::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Commit the new divider to the TICR register */
|
||||
HL::Pic::WriteApicRegister(APIC_TICR, NewDivider);
|
||||
@@ -1062,7 +1097,7 @@ HL::Timer::SetClockRateApic(ULONG Rate)
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/* Return the actual clock rate set */
|
||||
@@ -1174,7 +1209,7 @@ HL::Timer::StallExecutionAcpiPm(IN ULONG MicroSeconds)
|
||||
StartTick = CurrentTick;
|
||||
|
||||
/* Issue a PAUSE instruction to relieve memory bus contention */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1218,7 +1253,7 @@ HL::Timer::StallExecutionHpet(IN ULONG MicroSeconds)
|
||||
while((Hpet->MainCounterValue - StartTick) < TargetTicks)
|
||||
{
|
||||
/* Issue a PAUSE instruction to relieve memory bus contention */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1323,13 +1358,13 @@ HL::Timer::StallExecutionTsc(IN ULONG MicroSeconds)
|
||||
|
||||
/* Calculate target ticks based on calibrated TSC frequency */
|
||||
TargetTicks = ((ULONGLONG)MicroSeconds * PerformanceFrequency) / 1000000ULL;
|
||||
StartTick = AR::CpuFunc::ReadTimeStampCounter();
|
||||
StartTick = AR::CpuFunctions::ReadTimeStampCounter();
|
||||
|
||||
/* Spin until the elapsed ticks reach the target */
|
||||
while((AR::CpuFunc::ReadTimeStampCounter() - StartTick) < TargetTicks)
|
||||
while((AR::CpuFunctions::ReadTimeStampCounter() - StartTick) < TargetTicks)
|
||||
{
|
||||
/* Issue a PAUSE instruction to relieve memory bus contention */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Architecture-specific Library */
|
||||
namespace AR
|
||||
{
|
||||
class CpuFunc
|
||||
class CpuFunctions
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Architecture-specific Library */
|
||||
namespace AR
|
||||
{
|
||||
class ProcSup
|
||||
class ProcessorSupport
|
||||
{
|
||||
private:
|
||||
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Architecture-specific Library */
|
||||
namespace AR
|
||||
{
|
||||
class CpuFunc
|
||||
class CpuFunctions
|
||||
{
|
||||
public:
|
||||
STATIC XTCDECL VOID ClearInterruptFlag(VOID);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Architecture-specific Library */
|
||||
namespace AR
|
||||
{
|
||||
class ProcSup
|
||||
class ProcessorSupport
|
||||
{
|
||||
private:
|
||||
STATIC UCHAR BootStack[KERNEL_STACK_SIZE];
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace HL
|
||||
STATIC TIMER_TYPE TimerType;
|
||||
|
||||
public:
|
||||
STATIC XTAPI VOID InitializeLocalClock(VOID);
|
||||
STATIC XTAPI VOID InitializeTimer(VOID);
|
||||
STATIC XTAPI LARGE_INTEGER QueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);
|
||||
STATIC XTAPI ULONG SetClockRate(IN ULONG Rate);
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace MM
|
||||
STATIC SIZE_T BigAllocationsTrackingTableHash;
|
||||
STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;
|
||||
STATIC SIZE_T BigAllocationsTrackingTableSize;
|
||||
STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];
|
||||
|
||||
public:
|
||||
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
|
||||
@@ -65,6 +64,7 @@ namespace MM
|
||||
OUT PPFN_NUMBER PagesFreed);
|
||||
STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,
|
||||
OUT PPFN_NUMBER PagesFreed);
|
||||
STATIC XTAPI VOID PopulateAllocationTags(VOID);
|
||||
STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <rtl/llist.hh>
|
||||
#include <rtl/math.hh>
|
||||
#include <rtl/memory.hh>
|
||||
#include <rtl/rbtree.hh>
|
||||
#include <rtl/sha1.hh>
|
||||
#include <rtl/slist.hh>
|
||||
#include <rtl/string.hh>
|
||||
|
||||
45
xtoskrnl/includes/rtl/rbtree.hh
Normal file
45
xtoskrnl/includes/rtl/rbtree.hh
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/includes/rtl/rbtree.hh
|
||||
* DESCRIPTION: Red-Black Tree implementation
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef __XTOSKRNL_RTL_RBTREE_HH
|
||||
#define __XTOSKRNL_RTL_RBTREE_HH
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/* Runtime Library */
|
||||
namespace RTL
|
||||
{
|
||||
class RedBlackTree
|
||||
{
|
||||
public:
|
||||
STATIC XTAPI VOID InitializeTree(OUT PRTL_RB_TREE Tree);
|
||||
STATIC XTAPI VOID InsertNode(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Parent,
|
||||
IN PRTL_BALANCED_NODE Node,
|
||||
IN BOOLEAN RightChild);
|
||||
STATIC XTAPI VOID RemoveNode(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node);
|
||||
|
||||
private:
|
||||
STATIC XTAPI VOID CopyNodeColor(OUT PRTL_BALANCED_NODE Destination,
|
||||
IN PRTL_BALANCED_NODE Source);
|
||||
STATIC XTAPI RTL_BALANCED_NODE_COLOR GetNodeColor(IN PRTL_BALANCED_NODE Node);
|
||||
STATIC XTAPI PRTL_BALANCED_NODE GetParentNode(PRTL_BALANCED_NODE Node);
|
||||
STATIC XTAPI VOID RotateLeft(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node);
|
||||
STATIC XTAPI VOID RotateRight(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node);
|
||||
STATIC XTAPI VOID SetNodeColor(OUT PRTL_BALANCED_NODE Node,
|
||||
IN RTL_BALANCED_NODE_COLOR Color);
|
||||
STATIC XTAPI VOID SetParentNode(OUT PRTL_BALANCED_NODE Node,
|
||||
IN PRTL_BALANCED_NODE Parent);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __XTOSKRNL_RTL_RBTREE_HH */
|
||||
@@ -82,7 +82,7 @@ KD::DebugIo::DbgPrint(PCWSTR Format,
|
||||
/**
|
||||
* Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -211,7 +211,7 @@ KD::DebugIo::DetectDebugPorts(VOID)
|
||||
/**
|
||||
* Initializes the kernel's debugger I/O providers.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -249,7 +249,7 @@ KD::DebugIo::InitializeDebugIoProviders(VOID)
|
||||
/**
|
||||
* Initializes the framebuffer device provider for the kernel debugger.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -288,7 +288,7 @@ KD::DebugIo::InitializeFrameBufferProvider(VOID)
|
||||
/**
|
||||
* Initializes the serial port device provider for the kernel debugger.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -376,7 +376,7 @@ KD::DebugIo::SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine)
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -25,10 +25,13 @@ XTAPI
|
||||
VOID
|
||||
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
||||
|
||||
/* Initialize application CPU */
|
||||
AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
|
||||
/* Get processor control block */
|
||||
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Initialize processor */
|
||||
HL::Cpu::InitializeProcessor();
|
||||
@@ -39,12 +42,24 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
|
||||
/* Mark processor as started */
|
||||
StartBlock->Started = TRUE;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
/* Initialize CPU power state structures */
|
||||
PO::Idle::InitializeProcessorIdleState(ControlBlock);
|
||||
|
||||
/* Save processor state */
|
||||
KE::Processor::SaveProcessorState(&ControlBlock->ProcessorState);
|
||||
|
||||
/* Initialize per-CPU spin lock queues */
|
||||
KE::SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
KE::RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize local clock for this CPU */
|
||||
HL::Timer::InitializeLocalClock();
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n",
|
||||
ProcessorBlock->CpuNumber);
|
||||
ControlBlock->CpuNumber);
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
@@ -96,7 +111,7 @@ KE::KernelInit::BootstrapKernel(VOID)
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE);
|
||||
NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
@@ -185,7 +200,7 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
PVOID StartKernel;
|
||||
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() & ~(STACK_ALIGNMENT - 1));
|
||||
Stack = ((ULONG_PTR)AR::ProcessorSupport::GetBootStack() & ~(STACK_ALIGNMENT - 1));
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;
|
||||
@@ -198,7 +213,6 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
:
|
||||
: [Stack] "r" (Stack),
|
||||
[TargetRoutine] "r" (StartKernel),
|
||||
[TotalSize] "i" (FLOATING_SAVE_AREA_SIZE + KEXCEPTION_FRAME_SIZE +
|
||||
KSWITCH_FRAME_SIZE + KRETURN_ADDRESS_SIZE)
|
||||
[TotalSize] "i" (KTHREAD_STACK_OFFSET)
|
||||
: "memory", "rbp", "rsp");
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ PKPROCESSOR_BLOCK
|
||||
KE::Processor::GetCurrentProcessorBlock(VOID)
|
||||
{
|
||||
/* Get processor block from GS register */
|
||||
return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
|
||||
return (PKPROCESSOR_BLOCK)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +35,7 @@ XTAPI
|
||||
PKPROCESSOR_CONTROL_BLOCK
|
||||
KE::Processor::GetCurrentProcessorControlBlock(VOID)
|
||||
{
|
||||
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
|
||||
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ XTAPI
|
||||
ULONG
|
||||
KE::Processor::GetCurrentProcessorNumber(VOID)
|
||||
{
|
||||
return (ULONG)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
|
||||
return (ULONG)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ XTAPI
|
||||
PKTHREAD
|
||||
KE::Processor::GetCurrentThread(VOID)
|
||||
{
|
||||
return (PKTHREAD)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
|
||||
return (PKTHREAD)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,34 +192,34 @@ VOID
|
||||
KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
|
||||
{
|
||||
/* Save CR registers */
|
||||
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0);
|
||||
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2);
|
||||
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4);
|
||||
CpuState->SpecialRegisters.Cr8 = AR::CpuFunc::ReadControlRegister(8);
|
||||
CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);
|
||||
CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);
|
||||
CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);
|
||||
CpuState->SpecialRegisters.Cr8 = AR::CpuFunctions::ReadControlRegister(8);
|
||||
|
||||
/* Save DR registers */
|
||||
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0);
|
||||
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1);
|
||||
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2);
|
||||
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3);
|
||||
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6);
|
||||
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7);
|
||||
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);
|
||||
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);
|
||||
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);
|
||||
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);
|
||||
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);
|
||||
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);
|
||||
|
||||
/* Save MSR registers */
|
||||
CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_GSBASE);
|
||||
CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);
|
||||
CpuState->SpecialRegisters.MsrCStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_CSTAR);
|
||||
CpuState->SpecialRegisters.MsrLStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_LSTAR);
|
||||
CpuState->SpecialRegisters.MsrStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_STAR);
|
||||
CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_FMASK);
|
||||
CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_GSBASE);
|
||||
CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);
|
||||
CpuState->SpecialRegisters.MsrCStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_CSTAR);
|
||||
CpuState->SpecialRegisters.MsrLStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_LSTAR);
|
||||
CpuState->SpecialRegisters.MsrStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_STAR);
|
||||
CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_FMASK);
|
||||
|
||||
/* Save XMM control/status register */
|
||||
CpuState->SpecialRegisters.MxCsr = AR::CpuFunc::ReadMxCsrRegister();
|
||||
CpuState->SpecialRegisters.MxCsr = AR::CpuFunctions::ReadMxCsrRegister();
|
||||
|
||||
/* Save GDT, IDT, LDT and TaskRegister */
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
|
||||
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
|
||||
AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
|
||||
@@ -46,7 +46,7 @@ KE::BootInformation::GetFirmwareType(VOID)
|
||||
* @param Parameter
|
||||
* Supplies a pointer to a variable that receives a pointer to the matching parameter, or NULLPTR if not found.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -116,7 +116,7 @@ KE::BootInformation::GetKernelParameter(IN PCWSTR ParameterName,
|
||||
* @param BufferSize
|
||||
* Supplies the size of the value buffer, in wide characters.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -24,8 +24,8 @@ KE::Crash::HaltSystem(VOID)
|
||||
for(;;)
|
||||
{
|
||||
/* Halt system */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunc::Halt();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
AR::CpuFunctions::Halt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -56,7 +56,7 @@ KE::Dpc::InitializeDpc(IN PKDPC Dpc,
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.2
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -86,7 +86,7 @@ KE::Dpc::InitializeThreadedDpc(IN PKDPC Dpc,
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 4.0
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -104,7 +104,7 @@ KE::Dpc::SetTargetProcessor(IN PKDPC Dpc,
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.2
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -121,7 +121,7 @@ KE::Dpc::SignalCallDone(IN PVOID SystemArgument)
|
||||
*
|
||||
* @return This routine returns TRUE if just one processor is waiting on the barrier, FALSE if more.
|
||||
*
|
||||
* @since NT 5.2
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -41,7 +41,7 @@ KE::Event::ClearEvent(IN PKEVENT Event)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -71,7 +71,7 @@ KE::Event::InitializeEvent(OUT PKEVENT Event,
|
||||
*
|
||||
* @return This routine returns the previous signal state of the event.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
LONG
|
||||
|
||||
@@ -25,10 +25,13 @@ XTAPI
|
||||
VOID
|
||||
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
||||
|
||||
/* Initialize application CPU */
|
||||
AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
|
||||
/* Get processor control block */
|
||||
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
|
||||
|
||||
/* Initialize processor */
|
||||
HL::Cpu::InitializeProcessor();
|
||||
@@ -39,12 +42,24 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
|
||||
/* Mark processor as started */
|
||||
StartBlock->Started = TRUE;
|
||||
|
||||
/* Get current processor block */
|
||||
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||
/* Initialize CPU power state structures */
|
||||
PO::Idle::InitializeProcessorIdleState(ControlBlock);
|
||||
|
||||
/* Save processor state */
|
||||
KE::Processor::SaveProcessorState(&ControlBlock->ProcessorState);
|
||||
|
||||
/* Initialize per-CPU spin lock queues */
|
||||
KE::SpinLock::InitializeLockQueues();
|
||||
|
||||
/* Lower to APC runlevel */
|
||||
KE::RunLevel::LowerRunLevel(APC_LEVEL);
|
||||
|
||||
/* Initialize local clock for this CPU */
|
||||
HL::Timer::InitializeLocalClock();
|
||||
|
||||
/* Enter infinite loop */
|
||||
DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n",
|
||||
ProcessorBlock->CpuNumber);
|
||||
ControlBlock->CpuNumber);
|
||||
KE::Crash::HaltSystem();
|
||||
}
|
||||
|
||||
@@ -96,7 +111,7 @@ KE::KernelInit::BootstrapKernel(VOID)
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE);
|
||||
NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
@@ -185,7 +200,7 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
PVOID StartKernel;
|
||||
|
||||
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */
|
||||
Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() & ~(STACK_ALIGNMENT - 1));
|
||||
Stack = ((ULONG_PTR)AR::ProcessorSupport::GetBootStack() & ~(STACK_ALIGNMENT - 1));
|
||||
|
||||
/* Get address of KernelInit::StartKernel() */
|
||||
StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;
|
||||
@@ -200,6 +215,6 @@ KE::KernelInit::SwitchBootStack(VOID)
|
||||
: [Cr0Value] "i" (CR0_EM | CR0_MP | CR0_TS),
|
||||
[Stack] "r" (Stack),
|
||||
[TargetRoutine] "r" (StartKernel),
|
||||
[TotalSize] "i" (KTRAP_FRAME_ALIGN + KTRAP_FRAME_SIZE + NPX_FRAME_SIZE + KRETURN_ADDRESS_SIZE)
|
||||
[TotalSize] "i" (KTHREAD_STACK_OFFSET)
|
||||
: "ebp", "esp", "memory");
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
|
||||
PFX_SAVE_FORMAT FxSaveFormat;
|
||||
|
||||
/* Set initial thread frame */
|
||||
ThreadFrame = (PKTHREAD_INIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KTHREAD_INIT_FRAME));
|
||||
ThreadFrame = ((PKTHREAD_INIT_FRAME)Thread->InitialStack) - 1;
|
||||
|
||||
/* Fill floating point save area with zeroes */
|
||||
RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA));
|
||||
|
||||
@@ -21,7 +21,7 @@ PKPROCESSOR_BLOCK
|
||||
KE::Processor::GetCurrentProcessorBlock(VOID)
|
||||
{
|
||||
/* Get processor block from FS register */
|
||||
return (PKPROCESSOR_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
|
||||
return (PKPROCESSOR_BLOCK)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Self));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -35,7 +35,7 @@ XTAPI
|
||||
PKPROCESSOR_CONTROL_BLOCK
|
||||
KE::Processor::GetCurrentProcessorControlBlock(VOID)
|
||||
{
|
||||
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
|
||||
return (PKPROCESSOR_CONTROL_BLOCK)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CurrentPrcb));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +49,7 @@ XTAPI
|
||||
ULONG
|
||||
KE::Processor::GetCurrentProcessorNumber(VOID)
|
||||
{
|
||||
return (ULONG)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
|
||||
return (ULONG)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, CpuNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +63,7 @@ XTAPI
|
||||
PKTHREAD
|
||||
KE::Processor::GetCurrentThread(VOID)
|
||||
{
|
||||
return (PKTHREAD)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
|
||||
return (PKTHREAD)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,22 +192,22 @@ VOID
|
||||
KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
|
||||
{
|
||||
/* Save CR registers */
|
||||
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0);
|
||||
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2);
|
||||
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3);
|
||||
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4);
|
||||
CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);
|
||||
CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);
|
||||
CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);
|
||||
CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);
|
||||
|
||||
/* Save DR registers */
|
||||
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0);
|
||||
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1);
|
||||
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2);
|
||||
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3);
|
||||
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6);
|
||||
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7);
|
||||
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);
|
||||
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);
|
||||
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);
|
||||
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);
|
||||
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);
|
||||
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);
|
||||
|
||||
/* Save GDT, IDT, LDT and TaskRegister */
|
||||
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
|
||||
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
|
||||
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
|
||||
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
|
||||
AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
|
||||
AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
|
||||
AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
|
||||
AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the system's initial executive process object.
|
||||
*
|
||||
* @return This routine returns a pointer to the initial executive process.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PEPROCESS
|
||||
KE::KProcess::GetInitialProcess(VOID)
|
||||
@@ -36,7 +43,7 @@ KE::KProcess::GetInitialProcess(VOID)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
|
||||
@@ -47,7 +47,7 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
||||
}
|
||||
|
||||
/* Initialize boot CPU and set the unhandled interrupt routine */
|
||||
AR::ProcSup::InitializeProcessor(NULLPTR);
|
||||
AR::ProcessorSupport::InitializeProcessor(NULLPTR);
|
||||
AR::Traps::SetUnhandledInterruptRoutine(HL::Irq::HandleUnexpectedInterrupt);
|
||||
|
||||
/* Initialize system resources */
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the system's initial executive thread object.
|
||||
*
|
||||
* @return This routine returns a pointer to the initial executive thread.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PETHREAD
|
||||
KE::KThread::GetInitialThread(VOID)
|
||||
@@ -43,9 +50,9 @@ KE::KThread::GetInitialThread(VOID)
|
||||
* @param Stack
|
||||
* Supplies a pointer to the stack of the thread.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
XTSTATUS
|
||||
@@ -189,7 +196,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -75,7 +75,7 @@ KE::Semaphore::ReadState(IN PKSEMAPHORE Semaphore)
|
||||
*
|
||||
* @return This routine returns a previous signal state of the semaphore.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
LONG
|
||||
|
||||
@@ -49,12 +49,12 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
while(*(VOLATILE PKSPIN_LOCK)SpinLock & 1)
|
||||
{
|
||||
/* Yield processor and keep waiting */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add an explicit memory barrier */
|
||||
AR::CpuFunc::ReadWriteBarrier();
|
||||
AR::CpuFunctions::ReadWriteBarrier();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +137,7 @@ KE::SpinLock::InitializeLockQueues()
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -183,7 +183,7 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
|
||||
RTL::Atomic::And32((PLONG)SpinLock, 0);
|
||||
|
||||
/* Add an explicit memory barrier */
|
||||
AR::CpuFunc::ReadWriteBarrier();
|
||||
AR::CpuFunctions::ReadWriteBarrier();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +204,7 @@ TestSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||
if(*SpinLock)
|
||||
{
|
||||
/* Spinlock is busy, yield processor and return FALSE */
|
||||
AR::CpuFunc::YieldProcessor();
|
||||
AR::CpuFunctions::YieldProcessor();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @param ResourceHeader
|
||||
* Specifies a memory area where a pointer to the system resource header will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -62,10 +62,10 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Check if interrupts are enabled */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
Interrupts = AR::CpuFunctions::InterruptsEnabled();
|
||||
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Iterate through system resources list */
|
||||
@@ -114,7 +114,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
/* Return resource header and status code */
|
||||
@@ -131,7 +131,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
* @param ResourceHeader
|
||||
* Specifies a memory area where a pointer to the system resource header will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -147,7 +147,7 @@ KE::SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
|
||||
/**
|
||||
* Initializes system resource management.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -220,7 +220,7 @@ VOID
|
||||
KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
{
|
||||
/* Disable interrupts and acquire a spinlock */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::SpinLock::AcquireSpinLock(&ResourcesLock);
|
||||
|
||||
/* Release resource lock */
|
||||
@@ -228,5 +228,5 @@ KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
|
||||
|
||||
/* Release spinlock and enable interrupts */
|
||||
KE::SpinLock::ReleaseSpinLock(&ResourcesLock);
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise.
|
||||
*
|
||||
* @since NT 3.5
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
BOOLEAN
|
||||
@@ -57,7 +57,7 @@ KE::Timer::CancelTimer(IN PKTIMER Timer)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 4.0
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated pool of pages.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -192,7 +192,7 @@ MM::Allocator::AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated pool of pages.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -219,7 +219,7 @@ MM::Allocator::AllocatePagedPoolPages(IN PFN_COUNT Pages,
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated pool of pages.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -271,7 +271,7 @@ MM::Allocator::AllocatePages(IN MMPOOL_TYPE PoolType,
|
||||
* @param Memory
|
||||
* Supplies a pointer to the allocated memory.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -300,7 +300,7 @@ MM::Allocator::AllocatePool(IN MMPOOL_TYPE PoolType,
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -722,7 +722,7 @@ MM::Allocator::ExpandBigAllocationsTable(VOID)
|
||||
|
||||
/* Update the pool tracking statistics */
|
||||
UnregisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), PagesFreed << MM_PAGE_SHIFT, (MMPOOL_TYPE)0);
|
||||
RegisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), ROUND_UP(NewSize, MM_PAGE_SIZE), (MMPOOL_TYPE)0);
|
||||
RegisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), ROUND_UP(AllocationBytes, MM_PAGE_SIZE), (MMPOOL_TYPE)0);
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
@@ -737,7 +737,7 @@ MM::Allocator::ExpandBigAllocationsTable(VOID)
|
||||
* @param PagesFreed
|
||||
* Supplies a pointer to a variable that will receive the number of pages freed.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -985,7 +985,7 @@ MM::Allocator::FreeNonPagedPoolPages(IN PVOID VirtualAddress,
|
||||
* @param PagesFreed
|
||||
* Supplies a pointer to a variable that will receive the number of pages freed.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -1006,7 +1006,7 @@ MM::Allocator::FreePagedPoolPages(IN PVOID VirtualAddress,
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pages allocation to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -1026,7 +1026,7 @@ MM::Allocator::FreePages(IN PVOID VirtualAddress)
|
||||
* @param PagesFreed
|
||||
* Supplies a pointer to a variable that will receive the number of pages freed.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -1059,7 +1059,7 @@ MM::Allocator::FreePages(IN PVOID VirtualAddress,
|
||||
* @param VirtualAddress
|
||||
* Supplies the base virtual address of the pool allocation to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -1080,7 +1080,7 @@ MM::Allocator::FreePool(IN PVOID VirtualAddress)
|
||||
* @param Tag
|
||||
* Specifies the allocation identifying tag.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -1379,12 +1379,12 @@ MM::Allocator::InitializeAllocationsTracking(VOID)
|
||||
/* Zero the entire memory used by the table */
|
||||
RtlZeroMemory(AllocationsTrackingTable, AllocationsTrackingTableSize * sizeof(POOL_TRACKING_TABLE));
|
||||
|
||||
/* Assign the global tracking table as the local table for the bootstrap processor */
|
||||
TagTables[0] = AllocationsTrackingTable;
|
||||
|
||||
/* Calculate and store the hash mask */
|
||||
AllocationsTrackingTableMask = AllocationsTrackingTableSize - 2;
|
||||
|
||||
/* Populate the pool tracking table with the most frequently used allocation tags */
|
||||
PopulateAllocationTags();
|
||||
|
||||
/* Initialize the spinlock used to synchronize concurrent modifications to the tracking table */
|
||||
KE::SpinLock::InitializeSpinLock(&AllocationsTrackingTableLock);
|
||||
}
|
||||
@@ -1505,6 +1505,64 @@ MM::Allocator::InitializeBigAllocationsTracking(VOID)
|
||||
NonPagedPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the pool tracking table with the most frequently used allocation tags.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
MM::Allocator::PopulateAllocationTags(VOID)
|
||||
{
|
||||
ULONG Hash, HashIndex, Index;
|
||||
|
||||
CULONG HotTags[] =
|
||||
{
|
||||
SIGNATURE32('B', 'i', 'g', 'A'), /* Big Allocations */
|
||||
SIGNATURE32('M', 'M', 'g', 'r'), /* Memory Manager Internal */
|
||||
SIGNATURE32('N', 'o', 'n', 'e'), /* Untagged allocations */
|
||||
SIGNATURE32('O', 'v', 'f', 'l'), /* Global table expansion overflow fallback */
|
||||
};
|
||||
|
||||
/* Seed all tags */
|
||||
for(Index = 0; Index < ARRAY_SIZE(HotTags); Index++)
|
||||
{
|
||||
/* Compute the initial hash index */
|
||||
Hash = ComputeHash(HotTags[Index], AllocationsTrackingTableMask);
|
||||
HashIndex = Hash;
|
||||
|
||||
/* Probe the tracking table until an empty slot is found */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Check if the tag is already present in the table */
|
||||
if(AllocationsTrackingTable[Hash].Tag == HotTags[Index])
|
||||
{
|
||||
/* The tag has already been registered, skip it */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the slot is empty */
|
||||
if((AllocationsTrackingTable[Hash].Tag == 0) && (Hash != (AllocationsTrackingTableSize - 1)))
|
||||
{
|
||||
/* Claim the slot and break the loop */
|
||||
AllocationsTrackingTable[Hash].Tag = HotTags[Index];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Advance to the next index on collision */
|
||||
Hash = (Hash + 1) & AllocationsTrackingTableMask;
|
||||
|
||||
/* Check if the hash index has wrapped around */
|
||||
if(Hash == HashIndex)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a pool memory allocation in the tracking table.
|
||||
*
|
||||
@@ -1527,12 +1585,8 @@ MM::Allocator::RegisterAllocationTag(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType)
|
||||
{
|
||||
PPOOL_TRACKING_TABLE CpuTable, TableEntry;
|
||||
ULONG Hash, Index, Processor;
|
||||
|
||||
/* Retrieve the local tracking table for the current processor */
|
||||
Processor = KE::Processor::GetCurrentProcessorNumber();
|
||||
CpuTable = TagTables[Processor];
|
||||
PPOOL_TRACKING_TABLE TableEntry;
|
||||
ULONG Hash, Index;
|
||||
|
||||
/* Strip the protected pool bit */
|
||||
Tag &= ~MM_POOL_PROTECTED;
|
||||
@@ -1544,8 +1598,8 @@ MM::Allocator::RegisterAllocationTag(IN ULONG Tag,
|
||||
/* Probe the tracking table until a match or an empty slot is found */
|
||||
do
|
||||
{
|
||||
/* Fetch the tracker entry from the CPU table */
|
||||
TableEntry = &CpuTable[Hash];
|
||||
/* Fetch the tracker entry from the table */
|
||||
TableEntry = &AllocationsTrackingTable[Hash];
|
||||
|
||||
/* Check if the current entry tracks the requested pool tag */
|
||||
if(TableEntry->Tag == Tag)
|
||||
@@ -1568,34 +1622,21 @@ MM::Allocator::RegisterAllocationTag(IN ULONG Tag,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the CPU table is entirely empty */
|
||||
/* Check if the table is entirely empty */
|
||||
if(TableEntry->Tag == 0)
|
||||
{
|
||||
/* Check if another processor has claimed this slot in the global table */
|
||||
if(AllocationsTrackingTable[Hash].Tag != 0)
|
||||
{
|
||||
/* Synchronize the local table with the global table */
|
||||
TableEntry->Tag = AllocationsTrackingTable[Hash].Tag;
|
||||
|
||||
/* Restart the loop to evaluation */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if this is not the designated overflow bucket */
|
||||
if(Hash != (AllocationsTrackingTableSize - 1))
|
||||
{
|
||||
/* Start a guarded code block */
|
||||
{
|
||||
/* Acquire the tracking table lock */
|
||||
KE::SpinLockGuard TrackingTableLock(&AllocationsTrackingTableLock);
|
||||
/* Acquire the tracking table lock */
|
||||
KE::SpinLockGuard TrackingTableLock(&AllocationsTrackingTableLock);
|
||||
|
||||
/* Perform a double-checked lock */
|
||||
if(AllocationsTrackingTable[Hash].Tag == 0)
|
||||
{
|
||||
/* Claim the slot in both, local and global tracking tables */
|
||||
AllocationsTrackingTable[Hash].Tag = Tag;
|
||||
TableEntry->Tag = Tag;
|
||||
}
|
||||
/* Perform a double-checked lock */
|
||||
if(AllocationsTrackingTable[Hash].Tag == 0)
|
||||
{
|
||||
/* Claim the slot in both, local and global tracking tables */
|
||||
AllocationsTrackingTable[Hash].Tag = Tag;
|
||||
TableEntry->Tag = Tag;
|
||||
}
|
||||
|
||||
/* Restart the loop */
|
||||
@@ -1923,13 +1964,7 @@ MM::Allocator::UnregisterAllocationTag(IN ULONG Tag,
|
||||
IN MMPOOL_TYPE PoolType)
|
||||
{
|
||||
ULONG Hash, Index;
|
||||
PPOOL_TRACKING_TABLE CpuTable;
|
||||
PPOOL_TRACKING_TABLE TableEntry;
|
||||
ULONG Processor;
|
||||
|
||||
/* Retrieve the local tracking table for the current processor */
|
||||
Processor = KE::Processor::GetCurrentProcessorNumber();
|
||||
CpuTable = TagTables[Processor];
|
||||
|
||||
/* Strip the protected pool bit */
|
||||
Tag &= ~MM_POOL_PROTECTED;
|
||||
@@ -1941,8 +1976,8 @@ MM::Allocator::UnregisterAllocationTag(IN ULONG Tag,
|
||||
/* Probe the tracking table until a match or an empty slot is found */
|
||||
do
|
||||
{
|
||||
/* Fetch the tracker entry from the CPU table */
|
||||
TableEntry = &CpuTable[Hash];
|
||||
/* Fetch the tracker entry from the table */
|
||||
TableEntry = &AllocationsTrackingTable[Hash];
|
||||
|
||||
/* Check if the current entry tracks the requested pool tag */
|
||||
if(TableEntry->Tag == Tag)
|
||||
@@ -1952,33 +1987,19 @@ MM::Allocator::UnregisterAllocationTag(IN ULONG Tag,
|
||||
{
|
||||
/* Update the non-paged allocation statistics */
|
||||
RTL::Atomic::Increment32(&TableEntry->NonPagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->NonPagedBytes, 0 - Bytes);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->NonPagedBytes, -(LONG_PTR)Bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the paged allocation statistics */
|
||||
RTL::Atomic::Increment32(&TableEntry->PagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->PagedBytes, 0 - Bytes);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&TableEntry->PagedBytes, -(LONG_PTR)Bytes);
|
||||
}
|
||||
|
||||
/* The allocation has been successfully tracked, return */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the CPU table is entirely empty */
|
||||
if(TableEntry->Tag == 0)
|
||||
{
|
||||
/* Check if another processor has claimed this slot in the global table */
|
||||
if(AllocationsTrackingTable[Hash].Tag != 0)
|
||||
{
|
||||
/* Synchronize the local table with the global table */
|
||||
TableEntry->Tag = AllocationsTrackingTable[Hash].Tag;
|
||||
|
||||
/* Restart the loop to evaluation */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Advance to the next index as hash collision occurred */
|
||||
Hash = (Hash + 1) & AllocationsTrackingTableMask;
|
||||
}
|
||||
@@ -2010,9 +2031,7 @@ MM::Allocator::UnregisterAllocationTagExpansion(IN ULONG Tag,
|
||||
IN SIZE_T Bytes,
|
||||
IN MMPOOL_TYPE PoolType)
|
||||
{
|
||||
PPOOL_TRACKING_TABLE CpuTable;
|
||||
ULONG Hash;
|
||||
ULONG Processor;
|
||||
|
||||
/* Start a guarded code block */
|
||||
{
|
||||
@@ -2055,22 +2074,18 @@ MM::Allocator::UnregisterAllocationTagExpansion(IN ULONG Tag,
|
||||
/* Target the index of the overflow bucket */
|
||||
Hash = (ULONG)AllocationsTrackingTableSize - 1;
|
||||
|
||||
/* Retrieve the local tracking table for the current processor */
|
||||
Processor = KE::Processor::GetCurrentProcessorNumber();
|
||||
CpuTable = TagTables[Processor];
|
||||
|
||||
/* Update the appropriate statistics based on the pool type */
|
||||
if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)
|
||||
{
|
||||
/* Update the non-paged allocation statistics */
|
||||
RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].NonPagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].NonPagedBytes, 0 - Bytes);
|
||||
RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].NonPagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].NonPagedBytes, -(LONG_PTR)Bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the paged allocation statistics */
|
||||
RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].PagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].PagedBytes, 0 - Bytes);
|
||||
RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].PagedFrees);
|
||||
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].PagedBytes, -(LONG_PTR)Bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -96,7 +96,7 @@ MM::PageMap::GetNextEntry(IN PMMPTE Pte)
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ BOOLEAN
|
||||
MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
||||
{
|
||||
/* Check if LA57 is enabled */
|
||||
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
||||
return ((AR::CpuFunctions::ReadControlRegister(4) & CR4_LA57) != 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ MM::Paging::GetPxeVirtualAddress(IN PMMPXE PxePointer)
|
||||
* @param Attributes
|
||||
* Specifies the attributes (protections, caching) to apply to the PTE.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
* Specifies the virtual address to verify.
|
||||
*
|
||||
* @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTFASTCALL
|
||||
XTSTATUS
|
||||
|
||||
@@ -99,7 +99,7 @@ MM::Pte::InitializePageTable(VOID)
|
||||
MemoryLayout = MM::Manager::GetMemoryLayout();
|
||||
|
||||
/* Enable the Global Paging (PGE) feature */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PGE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PGE);
|
||||
|
||||
/* Check XPA status */
|
||||
if(Xpa)
|
||||
@@ -123,7 +123,7 @@ MM::Pte::InitializePageTable(VOID)
|
||||
}
|
||||
|
||||
/* Flush the TLB to invalidate all non-global entries */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Create a template PTE for mapping kernel pages */
|
||||
MM::Paging::ClearPte(&TemplatePte);
|
||||
|
||||
@@ -42,9 +42,6 @@ KSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;
|
||||
/* Maximum capacity of the tracking hash table */
|
||||
SIZE_T MM::Allocator::BigAllocationsTrackingTableSize;
|
||||
|
||||
/* Array of CPU-local tracking tables */
|
||||
PPOOL_TRACKING_TABLE MM::Allocator::TagTables[MM_POOL_TRACKING_TABLES];
|
||||
|
||||
/* Array of free page lists segregated by cache color */
|
||||
PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* @param Buffer
|
||||
* Supplies a buffer that receives the physical address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -153,7 +153,7 @@ MM::HardwarePool::AllocateHardwareMemory(IN PFN_NUMBER PageCount,
|
||||
* @param MemoryAddress
|
||||
* Supplies a pointer to a variable that receives the identity-mapped virtual address of the allocated memory.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -207,7 +207,7 @@ MM::HardwarePool::AllocateRealModeMemory(IN PFN_NUMBER PageCount,
|
||||
* @param VirtualAddress
|
||||
* Supplies a buffer that receives the virtual address of the mapped pages.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -374,7 +374,7 @@ MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress,
|
||||
* @param FlushTlb
|
||||
* Specifies whether to flush the TLB or not.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -251,7 +251,7 @@ MM::PageMapBasic::GetNextEntry(IN PMMPTE Pte)
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -472,7 +472,7 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
|
||||
* @param PtePointer
|
||||
* Pointer to the page table entry (PTE) to check.
|
||||
*
|
||||
* @return Returns TRUE if the entry is valid, FALSE otherwise.
|
||||
* @return This routine returns TRUE if the entry is valid, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -666,7 +666,7 @@ MM::PageMapBasic::WritePte(IN PMMPTE Pte,
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -721,7 +721,7 @@ MM::PageMapXpa::GetNextEntry(IN PMMPTE Pte)
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -942,7 +942,7 @@ MM::PageMapXpa::InitializePageMapInfo(VOID)
|
||||
* @param PtePointer
|
||||
* Pointer to the page table entry (PTE) to check.
|
||||
*
|
||||
* @return Returns TRUE if the entry is valid, FALSE otherwise.
|
||||
* @return This routine returns TRUE if the entry is valid, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ BOOLEAN
|
||||
MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
||||
{
|
||||
/* Check if PAE is enabled */
|
||||
return ((AR::CpuFunc::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE;
|
||||
return ((AR::CpuFunctions::ReadControlRegister(4) & CR4_PAE) != 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
|
||||
* @param Attributes
|
||||
* Specifies the attributes (protections, caching) to apply to the PTE.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -150,7 +150,7 @@ MM::Pfn::InitializePageTablePfns(VOID)
|
||||
RootLevel = 3;
|
||||
|
||||
/* Retrieve the PFN of the PML3 table and its virtual base address */
|
||||
PageFrameIndex = AR::CpuFunc::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
||||
PageFrameIndex = AR::CpuFunctions::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
||||
RootPte = (PMMPTE)MM::Paging::GetPpeAddress(NULLPTR);
|
||||
}
|
||||
else
|
||||
@@ -159,7 +159,7 @@ MM::Pfn::InitializePageTablePfns(VOID)
|
||||
RootLevel = 2;
|
||||
|
||||
/* Retrieve the PFN of the PML2 table and its virtual base address */
|
||||
PageFrameIndex = AR::CpuFunc::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
||||
PageFrameIndex = AR::CpuFunctions::ReadControlRegister(3) >> MM_PAGE_SHIFT;
|
||||
RootPte = (PMMPTE)MM::Paging::GetPdeAddress(NULLPTR);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,13 @@ MM::Pte::InitializePageTable(VOID)
|
||||
|
||||
/* Get CPU features */
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Check if Paging Global Extensions (PGE) is supported */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)
|
||||
{
|
||||
/* Enable the Global Paging (PGE) feature */
|
||||
AR::CpuFunc::WriteControlRegister(4, AR::CpuFunc::ReadControlRegister(4) | CR4_PGE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, AR::CpuFunctions::ReadControlRegister(4) | CR4_PGE);
|
||||
}
|
||||
|
||||
/* Get the PD user-space range for both legacy and PAE paging */
|
||||
@@ -91,7 +91,7 @@ MM::Pte::InitializePageTable(VOID)
|
||||
}
|
||||
|
||||
/* Flush the TLB to invalidate all non-global entries */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Create a template PTE for mapping kernel pages */
|
||||
MM::Paging::ClearPte(&TemplatePte);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* @param StackSize
|
||||
* Supplies the size of the stack to be allocated, in bytes.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -95,7 +95,7 @@ MM::KernelPool::AllocateKernelStack(OUT PVOID *Stack,
|
||||
* @param StructuresData
|
||||
* Supplies a pointer to the memory area that will contain the allocated buffer.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -279,13 +279,13 @@ MM::Manager::InitializeMemoryManager(VOID)
|
||||
MM::Pool::InitializePagedPool();
|
||||
|
||||
/* Flush TLB */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and maps the Kernel Shared Data page to its hardcoded virtual address.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
* @return This routine returns a status code indicating the success or failure of the operation.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* @param Count
|
||||
* The number of PTE entries to advance by.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -98,39 +98,39 @@ MM::Paging::FlushTlb(VOID)
|
||||
ULONG_PTR Cr4;
|
||||
|
||||
/* Save interrupts state and disable them */
|
||||
Interrupts = AR::CpuFunc::InterruptsEnabled();
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
Interrupts = AR::CpuFunctions::InterruptsEnabled();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
|
||||
/* Get CPU features */
|
||||
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
|
||||
AR::CpuFunc::CpuId(&CpuRegisters);
|
||||
AR::CpuFunctions::CpuId(&CpuRegisters);
|
||||
|
||||
/* Check if Paging Global Extensions (PGE) is supported */
|
||||
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)
|
||||
{
|
||||
/* Read CR4 */
|
||||
Cr4 = AR::CpuFunc::ReadControlRegister(4);
|
||||
Cr4 = AR::CpuFunctions::ReadControlRegister(4);
|
||||
|
||||
/* Disable PGE */
|
||||
AR::CpuFunc::WriteControlRegister(4, Cr4 & ~CR4_PGE);
|
||||
AR::CpuFunctions::WriteControlRegister(4, Cr4 & ~CR4_PGE);
|
||||
|
||||
/* Flush the TLB */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Restore CR4 */
|
||||
AR::CpuFunc::WriteControlRegister(4, Cr4);
|
||||
AR::CpuFunctions::WriteControlRegister(4, Cr4);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Simply flush the TLB */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
}
|
||||
|
||||
/* Check if interrupts should be enabled */
|
||||
if(Interrupts)
|
||||
{
|
||||
/* Re-enable interrupts */
|
||||
AR::CpuFunc::SetInterruptFlag();
|
||||
AR::CpuFunctions::SetInterruptFlag();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ MM::Paging::GetNextEntry(IN PMMPTE Pte)
|
||||
* @param Pte
|
||||
* The PTE pointer to advance.
|
||||
*
|
||||
* @return The advanced PTE pointer.
|
||||
* @return This routine returns the advanced PTE pointer.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
@@ -517,7 +517,7 @@ MM::Paging::InitializePageMapSupport(VOID)
|
||||
* @param PtePointer
|
||||
* Pointer to the page table entry (PTE) to check.
|
||||
*
|
||||
* @return Returns TRUE if the entry is valid, FALSE otherwise.
|
||||
* @return This routine returns TRUE if the entry is valid, FALSE otherwise.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -390,7 +390,7 @@ MM::Pfn::GetHighestPhysicalPage(VOID)
|
||||
/**
|
||||
* Retrieves the total number of physical pages managed by the system.
|
||||
*
|
||||
* @return Returns the total count of physical memory pages.
|
||||
* @return This routine returns the total count of physical memory pages.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
|
||||
@@ -539,7 +539,7 @@ MM::Pte::ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
|
||||
TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes;
|
||||
|
||||
/* Flush the TLB to ensure address translation consistency */
|
||||
AR::CpuFunc::FlushTlb();
|
||||
AR::CpuFunctions::FlushTlb();
|
||||
|
||||
/* Return a pointer to the start of the reserved PTE block */
|
||||
return ReservedPte;
|
||||
|
||||
@@ -63,7 +63,7 @@ PO::Idle::Idle0Function(IN PPROCESSOR_POWER_STATE PowerState)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
@@ -89,7 +89,7 @@ PO::Idle::PerfIdle(PPROCESSOR_POWER_STATE PowerState)
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since NT 5.1
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
|
||||
@@ -73,7 +73,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts and hang */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::Crash::Panic(0);
|
||||
|
||||
/* Continue search */
|
||||
@@ -128,6 +128,6 @@ _purecall(VOID)
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts and hang */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts and hang */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::Crash::Panic(0);
|
||||
|
||||
/* Continue search */
|
||||
@@ -128,6 +128,6 @@ _purecall(VOID)
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Disable interrupts and hang */
|
||||
AR::CpuFunc::ClearInterruptFlag();
|
||||
AR::CpuFunctions::ClearInterruptFlag();
|
||||
KE::Crash::Panic(0);
|
||||
}
|
||||
|
||||
723
xtoskrnl/rtl/rbtree.cc
Normal file
723
xtoskrnl/rtl/rbtree.cc
Normal file
@@ -0,0 +1,723 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtoskrnl/rtl/rbtree.cc
|
||||
* DESCRIPTION: Red-Black Tree implementation
|
||||
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||
*/
|
||||
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Copies the color from the Source node to the Dest node without modifying the destination node's parent pointer.
|
||||
*
|
||||
* @param Destination
|
||||
* Supplies a pointer to the balanced node for which to set the color.
|
||||
*
|
||||
* @param Source
|
||||
* Supplies a pointer to the balanced node from which to copy the color.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::CopyNodeColor(OUT PRTL_BALANCED_NODE Destination,
|
||||
IN PRTL_BALANCED_NODE Source)
|
||||
{
|
||||
/* Copy the color from the source node to the destination node */
|
||||
Destination->ParentValue = (Destination->ParentValue & ~RTL_BALANCED_NODE_COLOR_MASK) | GetNodeColor(Source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the color bit from the node's ParentValue.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node from which to extract the color.
|
||||
*
|
||||
* @return This routine returns the color of the given node, either NodeRed or NodeBlack.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
RTL_BALANCED_NODE_COLOR
|
||||
RTL::RedBlackTree::GetNodeColor(IN PRTL_BALANCED_NODE Node)
|
||||
{
|
||||
/* Return the node color */
|
||||
return (RTL_BALANCED_NODE_COLOR)(Node->ParentValue & RTL_BALANCED_NODE_COLOR_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the parent node pointer by masking out the reserved bits.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node from which to extract the parent pointer.
|
||||
*
|
||||
* @return This routine returns a pointer to the parent node of the given node.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PRTL_BALANCED_NODE
|
||||
RTL::RedBlackTree::GetParentNode(IN PRTL_BALANCED_NODE Node)
|
||||
{
|
||||
/* Return the parent node pointer by masking out the reserved bits */
|
||||
return (PRTL_BALANCED_NODE)(Node->ParentValue & ~RTL_BALANCED_NODE_RESERVED_PARENT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a red-black tree by setting its root and minimum pointers to NULLPTR.
|
||||
*
|
||||
* @param Tree
|
||||
* Supplies a pointer to the RTL_RB_TREE structure to initialize.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::InitializeTree(OUT PRTL_RB_TREE Tree)
|
||||
{
|
||||
/* Initialize the tree */
|
||||
Tree->Root = NULLPTR;
|
||||
Tree->Min = NULLPTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new node into the red-black tree at the specified position and rebalances the tree.
|
||||
*
|
||||
* @param Tree
|
||||
* Supplies a pointer to the RTL_RB_TREE structure into which the node is inserted.
|
||||
*
|
||||
* @param Parent
|
||||
* Supplies a pointer to the parent node under which the new node will be inserted.
|
||||
* If the tree is empty, this must be NULLPTR.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the uninitialized balanced node to insert into the tree.
|
||||
*
|
||||
* @param RightChild
|
||||
* Specifies whether the new node should be inserted as the right child (TRUE)
|
||||
* or the left child (FALSE) of the parent node.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::InsertNode(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Parent,
|
||||
IN PRTL_BALANCED_NODE Node,
|
||||
IN BOOLEAN RightChild)
|
||||
{
|
||||
PRTL_BALANCED_NODE CurrentNode, CurrentParent, GrandParent, Uncle;
|
||||
|
||||
/* Initialize the new node with no children and default its color to red */
|
||||
Node->Left = NULLPTR;
|
||||
Node->Right = NULLPTR;
|
||||
Node->ParentValue = (ULONG_PTR)Parent | NodeRed;
|
||||
|
||||
/* Check if the tree is not empty */
|
||||
if(Parent != NULLPTR)
|
||||
{
|
||||
/* Determine whether to attach the node as a right or left child */
|
||||
if(RightChild)
|
||||
{
|
||||
/* Attach the new node to the right side of the parent */
|
||||
Parent->Right = Node;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attach the new node to the left side of the parent */
|
||||
Parent->Left = Node;
|
||||
|
||||
/* Check if the new node is placed left of the current minimum */
|
||||
if(Parent == Tree->Min)
|
||||
{
|
||||
/* Update the cached minimum pointer for the tree */
|
||||
Tree->Min = Node;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The tree was empty, so the new node becomes both the root and the minimum */
|
||||
Tree->Root = Node;
|
||||
Tree->Min = Node;
|
||||
}
|
||||
|
||||
/* Begin fixing up the red-black tree properties */
|
||||
CurrentNode = Node;
|
||||
while(CurrentNode != Tree->Root && GetNodeColor(GetParentNode(CurrentNode)) == NodeRed)
|
||||
{
|
||||
/* Retrieve the parent and grandparent nodes to determine rotation and recoloring cases */
|
||||
CurrentParent = GetParentNode(CurrentNode);
|
||||
GrandParent = GetParentNode(CurrentParent);
|
||||
|
||||
/* Check if the parent is a left child of the grandparent */
|
||||
if(CurrentParent == GrandParent->Left)
|
||||
{
|
||||
/* Determine the uncle node */
|
||||
Uncle = GrandParent->Right;
|
||||
if(Uncle != NULLPTR && GetNodeColor(Uncle) == NodeRed)
|
||||
{
|
||||
/* Recolor parent, uncle, and grandparent */
|
||||
SetNodeColor(CurrentParent, NodeBlack);
|
||||
SetNodeColor(Uncle, NodeBlack);
|
||||
SetNodeColor(GrandParent, NodeRed);
|
||||
|
||||
/* Move the current node pointer up to the grandparent */
|
||||
CurrentNode = GrandParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if current node is a right child */
|
||||
if(CurrentNode == CurrentParent->Right)
|
||||
{
|
||||
/* Move the current pointer to the parent and perform a left rotation */
|
||||
CurrentNode = CurrentParent;
|
||||
RotateLeft(Tree, CurrentNode);
|
||||
|
||||
/* Update parent and grandparent pointers after the rotation */
|
||||
CurrentParent = GetParentNode(CurrentNode);
|
||||
GrandParent = GetParentNode(CurrentParent);
|
||||
}
|
||||
|
||||
/* Recolor parent and grandparent */
|
||||
SetNodeColor(CurrentParent, NodeBlack);
|
||||
SetNodeColor(GrandParent, NodeRed);
|
||||
|
||||
/* Perform a right rotation around the grandparent to restore tree balance */
|
||||
RotateRight(Tree, GrandParent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine the uncle node */
|
||||
Uncle = GrandParent->Left;
|
||||
if(Uncle != NULLPTR && GetNodeColor(Uncle) == NodeRed)
|
||||
{
|
||||
/* Recolor parent, uncle, and grandparent */
|
||||
SetNodeColor(CurrentParent, NodeBlack);
|
||||
SetNodeColor(Uncle, NodeBlack);
|
||||
SetNodeColor(GrandParent, NodeRed);
|
||||
|
||||
/* Move the current node pointer up to the grandparent */
|
||||
CurrentNode = GrandParent;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if current node is a left child */
|
||||
if(CurrentNode == CurrentParent->Left)
|
||||
{
|
||||
/* Move the current pointer to the parent and perform a right rotation */
|
||||
CurrentNode = CurrentParent;
|
||||
RotateRight(Tree, CurrentNode);
|
||||
|
||||
/* Update parent and grandparent pointers after the rotation */
|
||||
CurrentParent = GetParentNode(CurrentNode);
|
||||
GrandParent = GetParentNode(CurrentParent);
|
||||
}
|
||||
|
||||
/* Recolor parent and grandparent */
|
||||
SetNodeColor(CurrentParent, NodeBlack);
|
||||
SetNodeColor(GrandParent, NodeRed);
|
||||
|
||||
/* Perform a left rotation around the grandparent to restore tree balance */
|
||||
RotateLeft(Tree, GrandParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the root node is always colored black */
|
||||
SetNodeColor(Tree->Root, NodeBlack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified node from the red-black tree and rebalances the tree to maintain its properties.
|
||||
*
|
||||
* @param Tree
|
||||
* Supplies a pointer to the RTL_RB_TREE structure from which the node is removed.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node to remove from the tree.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::RemoveNode(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node)
|
||||
{
|
||||
PRTL_BALANCED_NODE CurrentNode, NextMinNode, NodeToRemove, ParentNode, Replacement, ReplacementParent, SiblingNode;
|
||||
ULONG_PTR RemoveNodeColor;
|
||||
|
||||
/* Initialize variables to track the node */
|
||||
NodeToRemove = Node;
|
||||
RemoveNodeColor = GetNodeColor(NodeToRemove);
|
||||
Replacement = NULLPTR;
|
||||
ReplacementParent = NULLPTR;
|
||||
|
||||
/* Check if the node being removed is the cached minimum node */
|
||||
if(Tree->Min == Node)
|
||||
{
|
||||
/* Find the next minimum node */
|
||||
NextMinNode = Node->Right;
|
||||
if(NextMinNode != NULLPTR)
|
||||
{
|
||||
/* Traverse to the leftmost descendant of the right child */
|
||||
while(NextMinNode->Left != NULLPTR)
|
||||
{
|
||||
/* Move down to the left child */
|
||||
NextMinNode = NextMinNode->Left;
|
||||
}
|
||||
|
||||
/* Update the tree's minimum pointer to the found successor */
|
||||
Tree->Min = NextMinNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The parent becomes the new minimum */
|
||||
Tree->Min = GetParentNode(Node);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the node to remove has no left child */
|
||||
if(Node->Left == NULLPTR)
|
||||
{
|
||||
/* Use the right child as the replacement node */
|
||||
Replacement = Node->Right;
|
||||
ReplacementParent = GetParentNode(Node);
|
||||
|
||||
/* Check if the removed node was the root of the tree */
|
||||
if(ReplacementParent == NULLPTR)
|
||||
{
|
||||
/* The replacement node becomes the new root */
|
||||
Tree->Root = Replacement;
|
||||
}
|
||||
else if(Node == ReplacementParent->Left)
|
||||
{
|
||||
/* Link the replacement to the parent's left side */
|
||||
ReplacementParent->Left = Replacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link the replacement to the parent's right side */
|
||||
ReplacementParent->Right = Replacement;
|
||||
}
|
||||
|
||||
/* Check if replacement exists */
|
||||
if(Replacement != NULLPTR)
|
||||
{
|
||||
/* Link the replacement back to its new parent */
|
||||
SetParentNode(Replacement, ReplacementParent);
|
||||
}
|
||||
}
|
||||
else if(Node->Right == NULLPTR)
|
||||
{
|
||||
/* Use the left child as the replacement node */
|
||||
Replacement = Node->Left;
|
||||
ReplacementParent = GetParentNode(Node);
|
||||
|
||||
/* Check if the removed node was the root of the tree */
|
||||
if(ReplacementParent == NULLPTR)
|
||||
{
|
||||
/* The replacement node becomes the new root */
|
||||
Tree->Root = Replacement;
|
||||
}
|
||||
else if(Node == ReplacementParent->Left)
|
||||
{
|
||||
/* Link the replacement to the parent's left side */
|
||||
ReplacementParent->Left = Replacement;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link the replacement to the parent's right side */
|
||||
ReplacementParent->Right = Replacement;
|
||||
}
|
||||
|
||||
/* Check if replacement exists */
|
||||
if(Replacement != NULLPTR)
|
||||
{
|
||||
/* Link the replacement back to its new parent */
|
||||
SetParentNode(Replacement, ReplacementParent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Find the in-order successor to replace it */
|
||||
NodeToRemove = Node->Right;
|
||||
while(NodeToRemove->Left != NULLPTR)
|
||||
{
|
||||
/* Traverse to the leftmost node in the right subtree */
|
||||
NodeToRemove = NodeToRemove->Left;
|
||||
}
|
||||
|
||||
/* Cache the original color of the successor node */
|
||||
RemoveNodeColor = GetNodeColor(NodeToRemove);
|
||||
Replacement = NodeToRemove->Right;
|
||||
ReplacementParent = GetParentNode(NodeToRemove);
|
||||
|
||||
/* Check fif the successor is not the direct right child of the node being removed */
|
||||
if(NodeToRemove != Node->Right)
|
||||
{
|
||||
/* Detach the successor from its original parent and link its right child */
|
||||
ReplacementParent->Left = Replacement;
|
||||
if(Replacement != NULLPTR)
|
||||
{
|
||||
/* Link the successor's right child to the successor's parent */
|
||||
SetParentNode(Replacement, ReplacementParent);
|
||||
}
|
||||
|
||||
/* Attach the original node's right subtree to the successor */
|
||||
NodeToRemove->Right = Node->Right;
|
||||
SetParentNode(NodeToRemove->Right, NodeToRemove);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the replacement parent as the successor itself */
|
||||
ReplacementParent = NodeToRemove;
|
||||
}
|
||||
|
||||
/* Retrieve the parent of the node being removed to link it to the successor */
|
||||
ParentNode = GetParentNode(Node);
|
||||
if(ParentNode == NULLPTR)
|
||||
{
|
||||
/* The successor becomes the new root */
|
||||
Tree->Root = NodeToRemove;
|
||||
}
|
||||
else if(Node == ParentNode->Left)
|
||||
{
|
||||
/* Link the successor to the left side of the original parent */
|
||||
ParentNode->Left = NodeToRemove;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link the successor to the right side of the original parent */
|
||||
ParentNode->Right = NodeToRemove;
|
||||
}
|
||||
|
||||
/* Update the parent pointer of the successor to its new parent */
|
||||
SetParentNode(NodeToRemove, ParentNode);
|
||||
NodeToRemove->Left = Node->Left;
|
||||
|
||||
/* Update the parent pointer of the left child and copy the original node's color */
|
||||
SetParentNode(NodeToRemove->Left, NodeToRemove);
|
||||
CopyNodeColor(NodeToRemove, Node);
|
||||
}
|
||||
|
||||
/* Check if the physically removed node was black */
|
||||
if(RemoveNodeColor == NodeBlack && Tree->Root != NULLPTR)
|
||||
{
|
||||
/* Fix up the tree properties */
|
||||
CurrentNode = Replacement;
|
||||
ParentNode = ReplacementParent;
|
||||
|
||||
/* Traverse up the tree */
|
||||
while(CurrentNode != Tree->Root &&
|
||||
(CurrentNode == NULLPTR || GetNodeColor(CurrentNode) == NodeBlack))
|
||||
{
|
||||
/* Check if the current node is a left child */
|
||||
if(CurrentNode == ParentNode->Left)
|
||||
{
|
||||
/* Identify the sibling node on the right */
|
||||
SiblingNode = ParentNode->Right;
|
||||
|
||||
/* Check if the sibling is red */
|
||||
if(GetNodeColor(SiblingNode) == NodeRed)
|
||||
{
|
||||
/* Recolor the sibling to black */
|
||||
SetNodeColor(SiblingNode, NodeBlack);
|
||||
SetNodeColor(ParentNode, NodeRed);
|
||||
|
||||
/* Perform a left rotation around the parent */
|
||||
RotateLeft(Tree, ParentNode);
|
||||
SiblingNode = ParentNode->Right;
|
||||
}
|
||||
|
||||
/* Check if both children of the sibling are black */
|
||||
if((SiblingNode->Left == NULLPTR || GetNodeColor(SiblingNode->Left) == NodeBlack) &&
|
||||
(SiblingNode->Right == NULLPTR || GetNodeColor(SiblingNode->Right) == NodeBlack))
|
||||
{
|
||||
/* Set the sibling color to red to restore black-height */
|
||||
SetNodeColor(SiblingNode, NodeRed);
|
||||
|
||||
/* Move the current pointer up to the parent and continue checking */
|
||||
CurrentNode = ParentNode;
|
||||
ParentNode = GetParentNode(CurrentNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the sibling's right child is black */
|
||||
if(SiblingNode->Right == NULLPTR || GetNodeColor(SiblingNode->Right) == NodeBlack)
|
||||
{
|
||||
/* Check if the left child needs updating */
|
||||
if(SiblingNode->Left != NULLPTR)
|
||||
{
|
||||
/* Recolor the sibling's left child */
|
||||
SetNodeColor(SiblingNode->Left, NodeBlack);
|
||||
}
|
||||
|
||||
/* Set the sibling to red and perform the right rotation */
|
||||
SetNodeColor(SiblingNode, NodeRed);
|
||||
RotateRight(Tree, SiblingNode);
|
||||
SiblingNode = ParentNode->Right;
|
||||
}
|
||||
|
||||
/* Swap colors between sibling and parent and recolor right child to black */
|
||||
CopyNodeColor(SiblingNode, ParentNode);
|
||||
SetNodeColor(ParentNode, NodeBlack);
|
||||
|
||||
/* Check if the right child needs updating */
|
||||
if(SiblingNode->Right != NULLPTR)
|
||||
{
|
||||
/* Recolor the sibling's right child */
|
||||
SetNodeColor(SiblingNode->Right, NodeBlack);
|
||||
}
|
||||
|
||||
/* Perform a left rotation around the parent to restore balance */
|
||||
RotateLeft(Tree, ParentNode);
|
||||
CurrentNode = Tree->Root;
|
||||
|
||||
/* The tree properties are restored, terminate the loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Process the case where the current node is a right child */
|
||||
SiblingNode = ParentNode->Left;
|
||||
|
||||
/* Check if the sibling is red */
|
||||
if(GetNodeColor(SiblingNode) == NodeRed)
|
||||
{
|
||||
/* Recolor the sibling to black */
|
||||
SetNodeColor(SiblingNode, NodeBlack);
|
||||
SetNodeColor(ParentNode, NodeRed);
|
||||
|
||||
/* Perform a right rotation around the parent */
|
||||
RotateRight(Tree, ParentNode);
|
||||
SiblingNode = ParentNode->Left;
|
||||
}
|
||||
|
||||
/* Check if both children of the sibling are black */
|
||||
if((SiblingNode->Right == NULLPTR || GetNodeColor(SiblingNode->Right) == NodeBlack) &&
|
||||
(SiblingNode->Left == NULLPTR || GetNodeColor(SiblingNode->Left) == NodeBlack))
|
||||
{
|
||||
/* Set the sibling color to red to restore black-height */
|
||||
SetNodeColor(SiblingNode, NodeRed);
|
||||
CurrentNode = ParentNode;
|
||||
ParentNode = GetParentNode(CurrentNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the sibling's left child is black */
|
||||
if(SiblingNode->Left == NULLPTR || GetNodeColor(SiblingNode->Left) == NodeBlack)
|
||||
{
|
||||
/* Check if the right child needs updating */
|
||||
if(SiblingNode->Right != NULLPTR)
|
||||
{
|
||||
/* Recolor the sibling's right child */
|
||||
SetNodeColor(SiblingNode->Right, NodeBlack);
|
||||
}
|
||||
|
||||
/* Set the sibling to red and perform the right rotation */
|
||||
SetNodeColor(SiblingNode, NodeRed);
|
||||
RotateLeft(Tree, SiblingNode);
|
||||
SiblingNode = ParentNode->Left;
|
||||
}
|
||||
|
||||
/* Swap colors between sibling and parent and recolor right child to black */
|
||||
CopyNodeColor(SiblingNode, ParentNode);
|
||||
SetNodeColor(ParentNode, NodeBlack);
|
||||
|
||||
/* Check if the left child needs updating */
|
||||
if(SiblingNode->Left != NULLPTR)
|
||||
{
|
||||
/* Recolor the sibling's left child */
|
||||
SetNodeColor(SiblingNode->Left, NodeBlack);
|
||||
}
|
||||
|
||||
/* Perform a right rotation around the parent */
|
||||
RotateRight(Tree, ParentNode);
|
||||
CurrentNode = Tree->Root;
|
||||
|
||||
/* The tree properties are restored, terminate the loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the current node is not null */
|
||||
if(CurrentNode != NULLPTR)
|
||||
{
|
||||
/* Force the current node to be black to satisfy the red-black rules */
|
||||
SetNodeColor(CurrentNode, NodeBlack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a left rotation around the specified node to maintain red-black tree balance.
|
||||
*
|
||||
* @param Tree
|
||||
* Supplies a pointer to the RTL_RB_TREE structure containing the node.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node around which to perform the left rotation.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::RotateLeft(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node)
|
||||
{
|
||||
PRTL_BALANCED_NODE ParentNode, RightNode;
|
||||
|
||||
/* Establish the right child as the pivot node for the rotation */
|
||||
RightNode = Node->Right;
|
||||
Node->Right = RightNode->Left;
|
||||
|
||||
/* Transfer the left subtree of the pivot to the right subtree of the node */
|
||||
if(RightNode->Left != NULLPTR)
|
||||
{
|
||||
/* Update the parent pointer */
|
||||
SetParentNode(RightNode->Left, Node);
|
||||
}
|
||||
|
||||
/* Update the parent */
|
||||
ParentNode = GetParentNode(Node);
|
||||
SetParentNode(RightNode, ParentNode);
|
||||
|
||||
/* Link the parent of the original node to the new pivot node */
|
||||
if(ParentNode == NULLPTR)
|
||||
{
|
||||
/* Set the pivot new root */
|
||||
Tree->Root = RightNode;
|
||||
}
|
||||
else if(Node == ParentNode->Left)
|
||||
{
|
||||
/* Update the left child pointer of the parent */
|
||||
ParentNode->Left = RightNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the right child pointer of the parent */
|
||||
ParentNode->Right = RightNode;
|
||||
}
|
||||
|
||||
/* Place the original node as the left child of the pivot */
|
||||
RightNode->Left = Node;
|
||||
SetParentNode(Node, RightNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a right rotation around the specified node to maintain red-black tree balance.
|
||||
*
|
||||
* @param Tree
|
||||
* Supplies a pointer to the RTL_RB_TREE structure containing the node.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node around which to perform the right rotation.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::RotateRight(IN PRTL_RB_TREE Tree,
|
||||
IN PRTL_BALANCED_NODE Node)
|
||||
{
|
||||
PRTL_BALANCED_NODE LeftNode, ParentNode;
|
||||
|
||||
/* Establish the left child as the pivot node for the rotation */
|
||||
LeftNode = Node->Left;
|
||||
Node->Left = LeftNode->Right;
|
||||
|
||||
/* Transfer the right subtree of the pivot to the left subtree of the node */
|
||||
if(LeftNode->Right != NULLPTR)
|
||||
{
|
||||
/* Update the parent pointer */
|
||||
SetParentNode(LeftNode->Right, Node);
|
||||
}
|
||||
|
||||
/* Update the parent */
|
||||
ParentNode = GetParentNode(Node);
|
||||
SetParentNode(LeftNode, ParentNode);
|
||||
|
||||
/* Link the parent of the original node to the new pivot node */
|
||||
if(ParentNode == NULLPTR)
|
||||
{
|
||||
/* Set the pivot new root */
|
||||
Tree->Root = LeftNode;
|
||||
}
|
||||
else if(Node == ParentNode->Right)
|
||||
{
|
||||
/* Update the right child pointer of the parent */
|
||||
ParentNode->Right = LeftNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the left child pointer of the parent */
|
||||
ParentNode->Left = LeftNode;
|
||||
}
|
||||
|
||||
/* Place the original node as the right child of the pivot */
|
||||
LeftNode->Right = Node;
|
||||
SetParentNode(Node, LeftNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the node's color. Clears the color bit first, then applies the new color.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node for which to set the color.
|
||||
*
|
||||
* @param Color
|
||||
* Specifies the new color to set for the node, either NodeRed or NodeBlack.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::SetNodeColor(OUT PRTL_BALANCED_NODE Node,
|
||||
IN RTL_BALANCED_NODE_COLOR Color)
|
||||
{
|
||||
/* Set the node color */
|
||||
Node->ParentValue = (Node->ParentValue & ~RTL_BALANCED_NODE_COLOR_MASK) | Color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parent node pointer while preserving the current color bits.
|
||||
*
|
||||
* @param Node
|
||||
* Supplies a pointer to the balanced node for which to set the parent pointer.
|
||||
*
|
||||
* @param Parent
|
||||
* Supplies a pointer to the new parent node to be set for the given node.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
RTL::RedBlackTree::SetParentNode(OUT PRTL_BALANCED_NODE Node,
|
||||
IN PRTL_BALANCED_NODE Parent)
|
||||
{
|
||||
/* Set the parent node pointer */
|
||||
Node->ParentValue = ((ULONG_PTR)Parent & ~RTL_BALANCED_NODE_RESERVED_PARENT_MASK) |
|
||||
(Node->ParentValue & RTL_BALANCED_NODE_RESERVED_PARENT_MASK);
|
||||
}
|
||||
Reference in New Issue
Block a user