Compare commits

22 Commits
smp ... master

Author SHA1 Message Date
a93ebbfb5b Populate pool tracking table with common allocation tags
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 36s
Builds / ExectOS (i686, release) (push) Successful in 33s
Builds / ExectOS (i686, debug) (push) Successful in 26s
Builds / ExectOS (amd64, release) (push) Successful in 30s
2026-05-23 17:40:40 +02:00
53726b5743 Correct pool tag registration size
Some checks failed
Builds / ExectOS (amd64, release) (push) Successful in 32s
Builds / ExectOS (i686, release) (push) Successful in 28s
Builds / ExectOS (amd64, debug) (push) Failing after 47s
Builds / ExectOS (i686, debug) (push) Successful in 45s
2026-05-22 23:55:02 +02:00
71870cd178 Remove per-CPU pool tracking tables
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (amd64, release) (push) Successful in 33s
Builds / ExectOS (amd64, debug) (push) Successful in 48s
Builds / ExectOS (i686, debug) (push) Successful in 46s
2026-05-22 23:45:32 +02:00
6f3b5b5e51 Clean up whitespace alignment
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 29s
Builds / ExectOS (amd64, release) (push) Successful in 44s
Builds / ExectOS (i686, debug) (push) Successful in 43s
Builds / ExectOS (i686, release) (push) Successful in 32s
2026-05-22 19:29:55 +02:00
6b689baa7a Rename initial stack reserve macro to KTHREAD_STACK_OFFSET
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 46s
Builds / ExectOS (i686, debug) (push) Successful in 44s
Builds / ExectOS (amd64, release) (push) Successful in 53s
Builds / ExectOS (i686, release) (push) Successful in 51s
2026-05-22 19:21:28 +02:00
9ac64605d3 Reserve initial thread frame space in AP startup stack
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 36s
Builds / ExectOS (i686, debug) (push) Successful in 34s
Builds / ExectOS (amd64, release) (push) Successful in 46s
Builds / ExectOS (i686, release) (push) Successful in 43s
2026-05-22 18:59:43 +02:00
102b357a75 Simplify thread frame setup using pointer arithmetic
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 29s
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (amd64, debug) (push) Successful in 46s
Builds / ExectOS (i686, debug) (push) Successful in 43s
2026-05-22 18:42:41 +02:00
6eb0b4d982 Unify initial stack reservation size calculation
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 32s
Builds / ExectOS (i686, debug) (push) Successful in 44s
Builds / ExectOS (amd64, debug) (push) Successful in 34s
Builds / ExectOS (amd64, release) (push) Successful in 45s
2026-05-22 18:40:07 +02:00
d8cb7c9242 Initialize per-CPU spin lock queues during AP bootstrap
All checks were successful
Builds / ExectOS (i686, debug) (push) Successful in 53s
Builds / ExectOS (amd64, debug) (push) Successful in 55s
Builds / ExectOS (amd64, release) (push) Successful in 11m59s
Builds / ExectOS (i686, release) (push) Successful in 11m56s
2026-05-22 15:27:59 +02:00
9002ac8b5c Implement red-black tree algorithm
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 40s
Builds / ExectOS (amd64, release) (push) Successful in 49s
Builds / ExectOS (i686, debug) (push) Successful in 38s
Builds / ExectOS (i686, release) (push) Successful in 46s
2026-05-21 14:56:44 +02:00
72a03f641d Update doxygen comments and formatting
All checks were successful
Builds / ExectOS (i686, debug) (push) Successful in 37s
Builds / ExectOS (amd64, debug) (push) Successful in 39s
Builds / ExectOS (amd64, release) (push) Successful in 49s
Builds / ExectOS (i686, release) (push) Successful in 46s
2026-05-20 20:52:52 +02:00
fe2e78f3c7 Extend AP bootstrap code
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 36s
Builds / ExectOS (i686, release) (push) Successful in 41s
Builds / ExectOS (amd64, release) (push) Successful in 44s
Builds / ExectOS (i686, debug) (push) Successful in 34s
2026-05-19 12:40:23 +02:00
6e4f0ba6e4 Implement per-processor local clock initialization
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 37s
Builds / ExectOS (i686, debug) (push) Successful in 33s
Builds / ExectOS (i686, release) (push) Successful in 39s
Builds / ExectOS (amd64, release) (push) Successful in 43s
2026-05-19 09:45:17 +02:00
19092eda2e Rename architecture CPU functions class
All checks were successful
Builds / ExectOS (amd64, release) (push) Successful in 37s
Builds / ExectOS (i686, debug) (push) Successful in 33s
Builds / ExectOS (i686, release) (push) Successful in 1m2s
Builds / ExectOS (amd64, debug) (push) Successful in 1m6s
2026-05-19 06:45:48 +02:00
b03cca65d8 Rename ProcSup class to ProcessorSupport and update all callers
Some checks failed
Builds / ExectOS (i686, release) (push) Successful in 2m17s
Builds / ExectOS (amd64, debug) (push) Successful in 2m24s
Builds / ExectOS (i686, debug) (push) Failing after 14m3s
Builds / ExectOS (amd64, release) (push) Failing after 14m7s
2026-05-18 22:55:54 +02:00
fec5bf65f1 Standardize doxygen in KD module
All checks were successful
Builds / ExectOS (i686, debug) (push) Successful in 36s
Builds / ExectOS (amd64, debug) (push) Successful in 37s
Builds / ExectOS (amd64, release) (push) Successful in 1m25s
Builds / ExectOS (i686, release) (push) Successful in 1m20s
2026-05-18 22:40:41 +02:00
7836dbe147 Fix parameter alignment and improve return value documentation
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 1m6s
Builds / ExectOS (i686, release) (push) Successful in 1m0s
Builds / ExectOS (amd64, release) (push) Successful in 1m36s
Builds / ExectOS (i686, debug) (push) Successful in 1m34s
2026-05-18 22:37:36 +02:00
297aba248b Correct doxygen tags to reflect XT kernel
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 31s
Builds / ExectOS (amd64, debug) (push) Successful in 31s
Builds / ExectOS (amd64, release) (push) Successful in 42s
Builds / ExectOS (i686, debug) (push) Successful in 40s
2026-05-18 20:27:05 +02:00
d41c90f541 Standardize doxygen return descriptions across HL layer
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 30s
Builds / ExectOS (amd64, release) (push) Successful in 34s
Builds / ExectOS (i686, debug) (push) Successful in 43s
Builds / ExectOS (amd64, debug) (push) Successful in 46s
2026-05-18 20:22:19 +02:00
f2c70d582a Update doxygen comments for RTC and timer functions
All checks were successful
Builds / ExectOS (amd64, debug) (push) Successful in 29s
Builds / ExectOS (i686, release) (push) Successful in 32s
Builds / ExectOS (amd64, release) (push) Successful in 45s
Builds / ExectOS (i686, debug) (push) Successful in 42s
2026-05-18 20:16:49 +02:00
24c9ae321c Update doxygen comments for AllocateSystemInterrupt and IOAPIC lookup routines
All checks were successful
Builds / ExectOS (i686, release) (push) Successful in 31s
Builds / ExectOS (i686, debug) (push) Successful in 43s
Builds / ExectOS (amd64, release) (push) Successful in 34s
Builds / ExectOS (amd64, debug) (push) Successful in 45s
2026-05-18 20:14:46 +02:00
7a18a2602f Merge pull request 'Add support for Symmetric Multiprocessing (SMP)' (#26) from smp into master
All checks were successful
Builds / ExectOS (i686, debug) (push) Successful in 36s
Builds / ExectOS (amd64, debug) (push) Successful in 37s
Builds / ExectOS (i686, release) (push) Successful in 44s
Builds / ExectOS (amd64, release) (push) Successful in 46s
2026-05-18 18:44:53 +02:00
80 changed files with 1617 additions and 704 deletions

View File

@@ -15,7 +15,7 @@
/* Minimal forward references for AR classes used by XTLDR */ /* Minimal forward references for AR classes used by XTLDR */
namespace AR namespace AR
{ {
class CpuFunc class CpuFunctions
{ {
public: public:
STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers); STATIC XTCDECL BOOLEAN CpuId(IN OUT PCPUID_REGISTERS Registers);
@@ -25,7 +25,7 @@ namespace AR
IN UINT_PTR Value); IN UINT_PTR Value);
}; };
class ProcSup class ProcessorSupport
{ {
public: public:
STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, STATIC XTAPI VOID GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,

View File

@@ -1032,7 +1032,7 @@ Protocol::InstallXtLoaderProtocol()
LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu; LoaderProtocol.Boot.RegisterMenu = XtLoader::RegisterBootMenu;
LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol; LoaderProtocol.Boot.RegisterProtocol = RegisterBootProtocol;
LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter; LoaderProtocol.BootUtils.GetBooleanParameter = BootUtils::GetBooleanParameter;
LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcSup::GetTrampolineInformation; LoaderProtocol.BootUtils.GetTrampolineInformation = AR::ProcessorSupport::GetTrampolineInformation;
LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue; LoaderProtocol.Config.GetBooleanValue = Configuration::GetBooleanValue;
LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue; LoaderProtocol.Config.GetBootOptionValue = Configuration::GetBootOptionValue;
LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions; LoaderProtocol.Config.GetEditableOptions = Configuration::GetEditableOptions;
@@ -1049,10 +1049,10 @@ Protocol::InstallXtLoaderProtocol()
LoaderProtocol.Console.SetAttributes = Console::SetAttributes; LoaderProtocol.Console.SetAttributes = Console::SetAttributes;
LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition; LoaderProtocol.Console.SetCursorPosition = Console::SetCursorPosition;
LoaderProtocol.Console.Write = Console::Write; LoaderProtocol.Console.Write = Console::Write;
LoaderProtocol.Cpu.CpuId = AR::CpuFunc::CpuId; LoaderProtocol.Cpu.CpuId = AR::CpuFunctions::CpuId;
LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunc::ReadControlRegister; LoaderProtocol.Cpu.ReadControlRegister = AR::CpuFunctions::ReadControlRegister;
LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunc::ReadModelSpecificRegister; LoaderProtocol.Cpu.ReadModelSpecificRegister = AR::CpuFunctions::ReadModelSpecificRegister;
LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunc::WriteControlRegister; LoaderProtocol.Cpu.WriteControlRegister = AR::CpuFunctions::WriteControlRegister;
LoaderProtocol.Debug.Print = Debug::Print; LoaderProtocol.Debug.Print = Debug::Print;
LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume; LoaderProtocol.Disk.CloseVolume = Volume::CloseVolume;
LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume; LoaderProtocol.Disk.OpenVolume = Volume::OpenVolume;

View File

@@ -85,6 +85,7 @@ GenerateAssemblyDefinitions(VOID)
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3); ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4); ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint); ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures); ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack); ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
ADK_OFFSET(PROCESSOR_START_BLOCK, Started); ADK_OFFSET(PROCESSOR_START_BLOCK, Started);

View File

@@ -59,6 +59,7 @@ GenerateAssemblyDefinitions(VOID)
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3); ADK_OFFSET(PROCESSOR_START_BLOCK, Cr3);
ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4); ADK_OFFSET(PROCESSOR_START_BLOCK, Cr4);
ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint); ADK_OFFSET(PROCESSOR_START_BLOCK, EntryPoint);
ADK_OFFSET(PROCESSOR_START_BLOCK, InitialStack);
ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures); ADK_OFFSET(PROCESSOR_START_BLOCK, ProcessorStructures);
ADK_OFFSET(PROCESSOR_START_BLOCK, Stack); ADK_OFFSET(PROCESSOR_START_BLOCK, Stack);
ADK_OFFSET(PROCESSOR_START_BLOCK, Started); ADK_OFFSET(PROCESSOR_START_BLOCK, Started);

View File

@@ -18,56 +18,56 @@
/* Selector masks */ /* Selector masks */
#define MODE_MASK 0x0001 #define MODE_MASK 0x0001
#define RPL_MASK 0x0003 #define RPL_MASK 0x0003
/* GDT selector names */ /* GDT selector names */
#define KGDT_NULL 0x0000 #define KGDT_NULL 0x0000
#define KGDT_R0_CMCODE 0x0008 #define KGDT_R0_CMCODE 0x0008
#define KGDT_R0_CODE 0x0010 #define KGDT_R0_CODE 0x0010
#define KGDT_R0_DATA 0x0018 #define KGDT_R0_DATA 0x0018
#define KGDT_R3_CMCODE 0x0020 #define KGDT_R3_CMCODE 0x0020
#define KGDT_R3_DATA 0x0028 #define KGDT_R3_DATA 0x0028
#define KGDT_R3_CODE 0x0030 #define KGDT_R3_CODE 0x0030
#define KGDT_SYS_TSS 0x0040 #define KGDT_SYS_TSS 0x0040
#define KGDT_R3_CMTEB 0x0050 #define KGDT_R3_CMTEB 0x0050
#define KGDT_R0_LDT 0x0060 #define KGDT_R0_LDT 0x0060
#define KGDT_ALIAS 0x0070 #define KGDT_ALIAS 0x0070
/* GDT descriptor privilege levels */ /* GDT descriptor privilege levels */
#define KGDT_DPL_SYSTEM 0 #define KGDT_DPL_SYSTEM 0
#define KGDT_DPL_USER 3 #define KGDT_DPL_USER 3
/* GDT descriptor properties */ /* GDT descriptor properties */
#define KGDT_DESCRIPTOR_ACCESSED 0x01 #define KGDT_DESCRIPTOR_ACCESSED 0x01
#define KGDT_DESCRIPTOR_READ_WRITE 0x02 #define KGDT_DESCRIPTOR_READ_WRITE 0x02
#define KGDT_DESCRIPTOR_EXECUTE_READ 0x02 #define KGDT_DESCRIPTOR_EXECUTE_READ 0x02
#define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04 #define KGDT_DESCRIPTOR_EXPAND_DOWN 0x04
#define KGDT_DESCRIPTOR_CONFORMING 0x04 #define KGDT_DESCRIPTOR_CONFORMING 0x04
#define KGDT_DESCRIPTOR_CODE 0x08 #define KGDT_DESCRIPTOR_CODE 0x08
/* GDT descriptor type codes */ /* GDT descriptor type codes */
#define KGDT_TYPE_NONE 0x00 #define KGDT_TYPE_NONE 0x00
#define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ) #define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ)
#define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE) #define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE)
/* IDT access levels */ /* IDT access levels */
#define KIDT_ACCESS_RING0 0x0 #define KIDT_ACCESS_RING0 0x0
#define KIDT_ACCESS_RING3 0x3 #define KIDT_ACCESS_RING3 0x3
/* IDT Interrupt Stack Table entries */ /* IDT Interrupt Stack Table entries */
#define KIDT_IST_RESERVED 0 #define KIDT_IST_RESERVED 0
#define KIDT_IST_PANIC 1 #define KIDT_IST_PANIC 1
#define KIDT_IST_MCA 2 #define KIDT_IST_MCA 2
#define KIDT_IST_NMI 3 #define KIDT_IST_NMI 3
/* AMD64 Segment Types */ /* AMD64 Segment Types */
#define AMD64_TASK_GATE 0x5 #define AMD64_TASK_GATE 0x5
#define AMD64_TSS 0x9 #define AMD64_TSS 0x9
#define AMD64_ACTIVE_TSS 0xB #define AMD64_ACTIVE_TSS 0xB
#define AMD64_CALL_GATE 0xC #define AMD64_CALL_GATE 0xC
#define AMD64_INTERRUPT_GATE 0xE #define AMD64_INTERRUPT_GATE 0xE
#define AMD64_TRAP_GATE 0xF #define AMD64_TRAP_GATE 0xF
/* Kernel CPU Standard Features */ /* Kernel CPU Standard Features */
#define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */ #define KCF_VME (1ULL << 0) /* Virtual 8086 Mode Enhancements */
@@ -126,33 +126,33 @@
#define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */ #define KCF_INVARIANT_TSC (1ULL << 10) /* Invariant Time Stamp Counter */
/* Context control flags */ /* Context control flags */
#define CONTEXT_ARCHITECTURE 0x00100000 #define CONTEXT_ARCHITECTURE 0x00100000
#define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01) #define CONTEXT_CONTROL (CONTEXT_ARCHITECTURE | 0x01)
#define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02) #define CONTEXT_INTEGER (CONTEXT_ARCHITECTURE | 0x02)
#define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04) #define CONTEXT_SEGMENTS (CONTEXT_ARCHITECTURE | 0x04)
#define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08) #define CONTEXT_FLOATING_POINT (CONTEXT_ARCHITECTURE | 0x08)
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10) #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARCHITECTURE | 0x10)
/* Interrupt request levels definitions */ /* Interrupt request levels definitions */
#define PASSIVE_LEVEL 0 #define PASSIVE_LEVEL 0
#define LOW_LEVEL 0 #define LOW_LEVEL 0
#define APC_LEVEL 1 #define APC_LEVEL 1
#define DISPATCH_LEVEL 2 #define DISPATCH_LEVEL 2
#define CMC_LEVEL 5 #define CMC_LEVEL 5
#define DEVICE1_LEVEL 6 #define DEVICE1_LEVEL 6
#define DEVICE2_LEVEL 7 #define DEVICE2_LEVEL 7
#define DEVICE3_LEVEL 8 #define DEVICE3_LEVEL 8
#define DEVICE4_LEVEL 9 #define DEVICE4_LEVEL 9
#define DEVICE5_LEVEL 10 #define DEVICE5_LEVEL 10
#define DEVICE6_LEVEL 11 #define DEVICE6_LEVEL 11
#define DEVICE7_LEVEL 12 #define DEVICE7_LEVEL 12
#define SYNC_LEVEL 12 #define SYNC_LEVEL 12
#define CLOCK_LEVEL 13 #define CLOCK_LEVEL 13
#define IPI_LEVEL 14 #define IPI_LEVEL 14
#define DRS_LEVEL 14 #define DRS_LEVEL 14
#define POWER_LEVEL 14 #define POWER_LEVEL 14
#define PROFILE_LEVEL 15 #define PROFILE_LEVEL 15
#define HIGH_LEVEL 15 #define HIGH_LEVEL 15
/* Size of the exception area */ /* Size of the exception area */
#define EXCEPTION_AREA_SIZE 64 #define EXCEPTION_AREA_SIZE 64
@@ -183,6 +183,9 @@
#define KTRAP_FRAME_ALIGN 0x10 #define KTRAP_FRAME_ALIGN 0x10
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME) #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 */ /* Return address size pushed by 'call' instruction */
#define KRETURN_ADDRESS_SIZE 0x8 #define KRETURN_ADDRESS_SIZE 0x8
@@ -532,6 +535,7 @@ typedef struct _PROCESSOR_START_BLOCK
ULONG_PTR Cr3; ULONG_PTR Cr3;
ULONG_PTR Cr4; ULONG_PTR Cr4;
PVOID EntryPoint; PVOID EntryPoint;
PVOID InitialStack;
PVOID ProcessorStructures; PVOID ProcessorStructures;
PVOID Stack; PVOID Stack;
BOOLEAN Started; BOOLEAN Started;

View File

@@ -119,9 +119,6 @@
/* Number of pool lists per page */ /* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE) #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 */ /* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__ #ifndef __XTOS_ASSEMBLER__

View File

@@ -201,6 +201,9 @@
#define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME) #define KTRAP_FRAME_SIZE sizeof(KTRAP_FRAME)
#define NPX_FRAME_SIZE 0x210 #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 */ /* Number of supported extensions */
#define MAXIMUM_SUPPORTED_EXTENSION 512 #define MAXIMUM_SUPPORTED_EXTENSION 512
@@ -493,6 +496,7 @@ typedef struct _PROCESSOR_START_BLOCK
ULONG_PTR Cr3; ULONG_PTR Cr3;
ULONG_PTR Cr4; ULONG_PTR Cr4;
PVOID EntryPoint; PVOID EntryPoint;
PVOID InitialStack;
PVOID ProcessorStructures; PVOID ProcessorStructures;
PVOID Stack; PVOID Stack;
BOOLEAN Started; BOOLEAN Started;

View File

@@ -117,9 +117,6 @@
/* Number of pool lists per page */ /* Number of pool lists per page */
#define MM_POOL_LISTS_PER_PAGE (MM_PAGE_SIZE / MM_POOL_BLOCK_SIZE) #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 */ /* C/C++ specific code */
#ifndef __XTOS_ASSEMBLER__ #ifndef __XTOS_ASSEMBLER__

View File

@@ -14,51 +14,55 @@
/* UUID string lengths */ /* UUID string lengths */
#define GUID_STRING_LENGTH 38 #define GUID_STRING_LENGTH 38
#define PARTUUID_STRING_LENGTH 13 #define PARTUUID_STRING_LENGTH 13
/* Maximum double/integer value string length */ /* Maximum double/integer value string length */
#define MAX_DOUBLE_STRING_SIZE 15 #define MAX_DOUBLE_STRING_SIZE 15
#define MAX_INTEGER_STRING_SIZE 25 #define MAX_INTEGER_STRING_SIZE 25
/* Floating point definitions */ /* Floating point definitions */
#define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL #define DOUBLE_EXPONENT_MASK 0x7FF0000000000000ULL
#define DOUBLE_EXPONENT_SHIFT 0x34 #define DOUBLE_EXPONENT_SHIFT 0x34
#define DOUBLE_EXPONENT_BIAS 0x3FF #define DOUBLE_EXPONENT_BIAS 0x3FF
#define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF #define DOUBLE_HIGH_VALUE_MASK 0x000FFFFF
#define DOUBLE_HIGH_VALUE_SHIFT 0x20 #define DOUBLE_HIGH_VALUE_SHIFT 0x20
#define DOUBLE_PRECISION 6 #define DOUBLE_PRECISION 6
#define DOUBLE_HEX_PRECISION 13 #define DOUBLE_HEX_PRECISION 13
#define DOUBLE_SCIENTIFIC_PRECISION -4 #define DOUBLE_SCIENTIFIC_PRECISION -4
#define DOUBLE_SIGN_BIT 0x8000000000000000ULL #define DOUBLE_SIGN_BIT 0x8000000000000000ULL
/* Print flag definitions */ /* Print flag definitions */
#define PFL_ALWAYS_PRINT_SIGN 0x00000001 #define PFL_ALWAYS_PRINT_SIGN 0x00000001
#define PFL_SPACE_FOR_PLUS 0x00000002 #define PFL_SPACE_FOR_PLUS 0x00000002
#define PFL_LEFT_JUSTIFIED 0x00000004 #define PFL_LEFT_JUSTIFIED 0x00000004
#define PFL_LEADING_ZEROES 0x00000008 #define PFL_LEADING_ZEROES 0x00000008
#define PFL_LONG_INTEGER 0x00000010 #define PFL_LONG_INTEGER 0x00000010
#define PFL_LONG_DOUBLE 0x00000020 #define PFL_LONG_DOUBLE 0x00000020
#define PFL_WIDE_CHARACTER 0x00000040 #define PFL_WIDE_CHARACTER 0x00000040
#define PFL_SHORT_VALUE 0x00000080 #define PFL_SHORT_VALUE 0x00000080
#define PFL_UNSIGNED 0x00000100 #define PFL_UNSIGNED 0x00000100
#define PFL_UPPERCASE 0x00000200 #define PFL_UPPERCASE 0x00000200
#define PFL_PRINT_RADIX 0x00000400 #define PFL_PRINT_RADIX 0x00000400
#define PFL_FLOAT_FORMAT 0x00000800 #define PFL_FLOAT_FORMAT 0x00000800
#define PFL_SCI_FORMAT 0x00001000 #define PFL_SCI_FORMAT 0x00001000
#define PFL_DIGIT_PRECISION 0x00002000 #define PFL_DIGIT_PRECISION 0x00002000
#define PFL_THOUSANDS_GROUPING 0x00004000 #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 */ /* Cryptographic related definitions */
#define SHA1_BLOCK_SIZE 64 #define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20 #define SHA1_DIGEST_SIZE 20
/* Time related definitions */ /* Time related definitions */
#define TIME_SECONDS_PER_MINUTE 60 #define TIME_SECONDS_PER_MINUTE 60
#define TIME_SECONDS_PER_HOUR 3600 #define TIME_SECONDS_PER_HOUR 3600
#define TIME_SECONDS_PER_DAY 86400 #define TIME_SECONDS_PER_DAY 86400
#define TIME_TICKS_PER_SECOND 10000000 #define TIME_TICKS_PER_SECOND 10000000
#define TIME_TICKS_PER_MILLISECOND 10000 #define TIME_TICKS_PER_MILLISECOND 10000
/* C/C++ specific code */ /* C/C++ specific code */
@@ -68,6 +72,13 @@
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character); typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR 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 */ /* Variable types enumeration list */
typedef enum _RTL_VARIABLE_TYPE typedef enum _RTL_VARIABLE_TYPE
{ {
@@ -84,6 +95,26 @@ typedef enum _RTL_VARIABLE_TYPE
TypeWideString TypeWideString
} RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE; } 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 */ /* Bit Map structure definition */
typedef struct _RTL_BITMAP typedef struct _RTL_BITMAP
{ {
@@ -110,12 +141,19 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
LONG Flags; LONG Flags;
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES; } 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 */ /* Runtime Library SHA-1 context structure definition */
typedef struct _RTL_SHA1_CONTEXT typedef struct _RTL_SHA1_CONTEXT
{ {
ULONG State[5]; ULONG State[5];
ULONG Count[2]; ULONG Count[2];
UCHAR Buffer[SHA1_BLOCK_SIZE]; UCHAR Buffer[SHA1_BLOCK_SIZE];
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT; } RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
/* Runtime time fields structure definition */ /* Runtime time fields structure definition */

View File

@@ -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 _MMPOOL_TYPE MMPOOL_TYPE, *PMMPOOL_TYPE;
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE; typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE, *PMMSYSTEM_PTE_POOL_TYPE;
typedef enum _MODE MODE, *PMODE; 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 _RTL_VARIABLE_TYPE RTL_VARIABLE_TYPE, *PRTL_VARIABLE_TYPE;
typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE;
typedef enum _SYSTEM_RESOURCE_TYPE SYSTEM_RESOURCE_TYPE, *PSYSTEM_RESOURCE_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 _POOL_TRACKING_TABLE POOL_TRACKING_TABLE, *PPOOL_TRACKING_TABLE;
typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY; typedef struct _PROCESSOR_IDENTITY PROCESSOR_IDENTITY, *PPROCESSOR_IDENTITY;
typedef struct _PROCESSOR_POWER_STATE PROCESSOR_POWER_STATE, *PPROCESSOR_POWER_STATE; 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_BITMAP RTL_BITMAP, *PRTL_BITMAP;
typedef struct _RTL_PRINT_CONTEXT RTL_PRINT_CONTEXT, *PRTL_PRINT_CONTEXT; 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_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 _SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER; typedef struct _SMBIOS_TABLE_HEADER SMBIOS_TABLE_HEADER, *PSMBIOS_TABLE_HEADER;
typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER; typedef struct _SMBIOS3_TABLE_HEADER SMBIOS3_TABLE_HEADER, *PSMBIOS3_TABLE_HEADER;

View File

@@ -88,6 +88,7 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc ${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc ${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc ${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
${XTOSKRNL_SOURCE_DIR}/rtl/rbtree.cc
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc ${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc ${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc ${XTOSKRNL_SOURCE_DIR}/rtl/string.cc

View File

@@ -463,7 +463,7 @@ ApEnterLongMode:
movl %edi, %edi movl %edi, %edi
/* Load dedicated Stack for AP */ /* 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 */ /* Save the pointer to PROCESSOR_START_BLOCK */
movq %rdi, %rcx movq %rdi, %rcx

View File

@@ -18,7 +18,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::ClearInterruptFlag(VOID) AR::CpuFunctions::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
* @param Registers * @param Registers
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::FlushTlb(VOID) AR::CpuFunctions::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
WriteControlRegister(3, ReadControlRegister(3)); WriteControlRegister(3, ReadControlRegister(3));
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
AR::CpuFunc::GetCpuFlags(VOID) AR::CpuFunctions::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::GetStackPointer(VOID) AR::CpuFunctions::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("movq %%rsp, %%rax\n" __asm__ volatile("movq %%rsp, %%rax\n"
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::Halt(VOID) AR::CpuFunctions::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
AR::CpuFunc::InterruptsEnabled(VOID) AR::CpuFunctions::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address) AR::CpuFunctions::InvalidateTlbEntry(IN PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(IN PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -251,7 +251,7 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source) AR::CpuFunctions::LoadMxcsrRegister(IN ULONG Source)
{ {
__asm__ volatile("ldmxcsr %0" __asm__ volatile("ldmxcsr %0"
: :
@@ -273,7 +273,7 @@ AR::CpuFunc::LoadMxcsrRegister(IN ULONG Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadSegment(IN USHORT Segment, AR::CpuFunctions::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
@@ -335,7 +335,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadTaskRegister(USHORT Source) AR::CpuFunctions::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -351,7 +351,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::MemoryBarrier(VOID) AR::CpuFunctions::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("lock; orl $0, %0;" __asm__ volatile("lock; orl $0, %0;"
@@ -365,13 +365,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
* @param ControlRegister * @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister) AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -429,13 +429,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
* @param DebugRegister * @param DebugRegister
* Supplies a number of a debug register to read from. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -498,13 +498,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
* @param Offset * @param Offset
* Specifies the offset from the beginning of GS segment. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadGSQuadWord(ULONG Offset) AR::CpuFunctions::ReadGSQuadWord(ULONG Offset)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -527,7 +527,7 @@ AR::CpuFunc::ReadGSQuadWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register) AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONG Low, High; ULONG Low, High;
@@ -548,7 +548,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
AR::CpuFunc::ReadMxCsrRegister(VOID) AR::CpuFunctions::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -562,7 +562,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadTimeStampCounter(VOID) AR::CpuFunctions::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Low, High; ULONGLONG Low, High;
@@ -585,7 +585,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux) AR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
{ {
ULONG Low, High; ULONG Low, High;
@@ -609,7 +609,7 @@ AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::ReadWriteBarrier(VOID) AR::CpuFunctions::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -626,7 +626,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::SetInterruptFlag(VOID) AR::CpuFunctions::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -643,7 +643,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -663,7 +663,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -683,7 +683,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -706,8 +706,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreSegment(IN USHORT Segment, AR::CpuFunctions::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
{ {
@@ -753,7 +753,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination) AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -776,8 +776,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister, AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
switch(ControlRegister) switch(ControlRegister)
@@ -835,8 +835,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
switch(DebugRegister) switch(DebugRegister)
@@ -912,7 +912,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -935,8 +935,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register, AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
ULONG Low = Value & 0xFFFFFFFF; ULONG Low = Value & 0xFFFFFFFF;
ULONG High = Value >> 32; ULONG High = Value >> 32;
@@ -957,7 +957,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::YieldProcessor(VOID) AR::CpuFunctions::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :

View File

@@ -10,25 +10,25 @@
/* Initial kernel boot stack */ /* Initial kernel boot stack */
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
/* Initial kernel fault stack */ /* Initial kernel fault stack */
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */ /* Initial GDT */
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {}; KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */ /* Initial IDT */
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {}; KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */ /* Initial Processor Block */
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock; KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
/* Initial TSS */ /* Initial TSS */
KTSS AR::ProcSup::InitialTss; KTSS AR::ProcessorSupport::InitialTss;
/* Initial kernel NMI stack */ /* Initial kernel NMI stack */
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
/* Unhandled interrupt routine */ /* Unhandled interrupt routine */
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR; PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;

View File

@@ -18,7 +18,7 @@
*/ */
XTAPI XTAPI
PVOID PVOID
AR::ProcSup::GetBootStack(VOID) AR::ProcessorSupport::GetBootStack(VOID)
{ {
/* Return base address of kernel boot stack */ /* Return base address of kernel boot stack */
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE); return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
@@ -26,9 +26,9 @@ AR::ProcSup::GetBootStack(VOID)
XTAPI XTAPI
VOID VOID
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize) OUT PULONG_PTR TrampolineSize)
{ {
/* Get trampoline information */ /* Get trampoline information */
switch(TrampolineType) switch(TrampolineType)
@@ -63,7 +63,7 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessor(VOID) AR::ProcessorSupport::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -75,7 +75,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
@@ -87,7 +87,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -137,7 +137,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessorFeatures(VOID) AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
{ {
ULONG MaxExtendedLeaf, MaxStandardLeaf; ULONG MaxExtendedLeaf, MaxStandardLeaf;
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
@@ -149,13 +149,13 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get maximum CPUID standard leaf */ /* Get maximum CPUID standard leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
MaxStandardLeaf = CpuRegisters.Eax; MaxStandardLeaf = CpuRegisters.Eax;
/* Get maximum CPUID extended leaf */ /* Get maximum CPUID extended leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX; CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
MaxExtendedLeaf = CpuRegisters.Eax; MaxExtendedLeaf = CpuRegisters.Eax;
/* Check if CPU supports standard features leaf */ /* Check if CPU supports standard features leaf */
@@ -164,7 +164,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU standard features in processor control block */ /* Store CPU standard features in processor control block */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3; if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
@@ -208,7 +208,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU standard7 features in processor control block */ /* Store CPU standard7 features in processor control block */
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE; 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 */ /* Get CPU power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT; CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU power management features in processor control block */ /* Store CPU power management features in processor control block */
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT; if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
@@ -238,7 +238,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU extended features */ /* Get CPU extended features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES; CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU extended features in processor control block */ /* Store CPU extended features in processor control block */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM; 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 */ /* Get CPU advanced power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT; 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 */ /* Store CPU advanced power management features in processor control block */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC; if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
@@ -278,7 +278,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 1);
@@ -307,7 +307,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -355,7 +355,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack; PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
KDESCRIPTOR GdtDescriptor, IdtDescriptor; KDESCRIPTOR GdtDescriptor, IdtDescriptor;
@@ -401,16 +401,16 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */ /* Load GDT, IDT and TSS */
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Initialize segment registers */ /* Initialize segment registers */
InitializeSegments(); InitializeSegments();
/* Set GS base */ /* Set GS base */
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock);
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock);
/* Initialize processor registers */ /* Initialize processor registers */
InitializeProcessorRegisters(); InitializeProcessorRegisters();
@@ -440,11 +440,11 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack) IN PVOID DpcStack)
{ {
/* Set processor block and processor control block */ /* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->Self = ProcessorBlock;
@@ -490,50 +490,51 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorRegisters(VOID) AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
{ {
ULONGLONG PatAttributes; ULONGLONG PatAttributes;
/* Enable FXSAVE restore */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ /* Flush the TLB */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
/* Initialize system call MSRs */ /* Initialize system call MSRs */
AR::Traps::InitializeSystemCallMsrs(); AR::Traps::InitializeSystemCallMsrs();
/* Enable No-Execute (NXE) in EFER MSR */ /* 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 */ /* Initialize Page Attribute Table */
PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) | PatAttributes = (PAT_TYPE_WB << 0) | (PAT_TYPE_USWC << 8) | (PAT_TYPE_WEAK_UC << 16) | (PAT_TYPE_STRONG_UC << 24) |
(PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56); (PAT_TYPE_WB << 32) | (PAT_TYPE_USWC << 40) | (PAT_TYPE_WEAK_UC << 48) | (PAT_TYPE_STRONG_UC << 56);
AR::CpuFunc::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes); AR::CpuFunctions::WriteModelSpecificRegister(X86_MSR_PAT, PatAttributes);
/* Initialize MXCSR register */ /* Initialize MXCSR register */
AR::CpuFunc::LoadMxcsrRegister(INITIAL_MXCSR); AR::CpuFunctions::LoadMxcsrRegister(INITIAL_MXCSR);
} }
/** /**
@@ -563,13 +564,13 @@ AR::ProcSup::InitializeProcessorRegisters(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack, OUT PVOID *KernelFaultStack,
OUT PVOID *KernelNmiStack) OUT PVOID *KernelNmiStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -631,15 +632,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeSegments(VOID) AR::ProcessorSupport::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R3_CMTEB | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_GS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA); AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -657,10 +658,10 @@ AR::ProcSup::InitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack, IN PVOID KernelFaultStack,
IN PVOID KernelNmiStack) IN PVOID KernelNmiStack)
{ {
/* Fill TSS with zeroes */ /* Fill TSS with zeroes */
RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS)); RtlZeroMemory(ProcessorBlock->TssBase, sizeof(KTSS));
@@ -703,13 +704,13 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, AR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
IN UCHAR Type, IN UCHAR Type,
IN UCHAR Dpl, IN UCHAR Dpl,
IN UCHAR SegmentMode) IN UCHAR SegmentMode)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
UCHAR Granularity; UCHAR Granularity;
@@ -769,9 +770,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base) IN ULONG_PTR Base)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
@@ -815,13 +816,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt, AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
IN USHORT Ist, IN USHORT Ist,
IN USHORT Dpl, IN USHORT Dpl,
IN USHORT Type) IN USHORT Type)
{ {
/* Set the handler's address */ /* Set the handler's address */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF); Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);

View File

@@ -26,8 +26,8 @@ AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
PINTERRUPT_HANDLER Handler; PINTERRUPT_HANDLER Handler;
/* Read the handler pointer from the CPU's interrupt dispatch table */ /* Read the handler pointer from the CPU's interrupt dispatch table */
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) + Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER))); (TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
/* Check if the interrupt has a handler registered */ /* Check if the interrupt has a handler registered */
if(Handler != NULLPTR) if(Handler != NULLPTR)
@@ -672,13 +672,13 @@ VOID
AR::Traps::InitializeSystemCallMsrs(VOID) AR::Traps::InitializeSystemCallMsrs(VOID)
{ {
/* Initialize system calls MSR */ /* Initialize system calls MSR */
CpuFunc::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32)); CpuFunctions::WriteModelSpecificRegister(X86_MSR_STAR, (((ULONG64)KGDT_R3_CMCODE | RPL_MASK) << 48) | ((ULONG64)KGDT_R0_CODE << 32));
CpuFunc::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32); CpuFunctions::WriteModelSpecificRegister(X86_MSR_CSTAR, (ULONG64)&HandleSystemCall32);
CpuFunc::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64); CpuFunctions::WriteModelSpecificRegister(X86_MSR_LSTAR, (ULONG64)&HandleSystemCall64);
CpuFunc::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK); CpuFunctions::WriteModelSpecificRegister(X86_MSR_FMASK, X86_EFLAGS_IF_MASK | X86_EFLAGS_TF_MASK);
/* Enable system call extensions (SCE) in EFER MSR */ /* 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);
} }
/** /**

View File

@@ -311,7 +311,7 @@ ApEnterProtectedMode:
movl %eax, %cr0 movl %eax, %cr0
/* Load dedicated Stack for AP */ /* 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 */ /* Save the pointer to PROCESSOR_START_BLOCK */
movl %edi, %ecx movl %edi, %ecx

View File

@@ -18,7 +18,7 @@
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::ClearInterruptFlag(VOID) AR::CpuFunctions::ClearInterruptFlag(VOID)
{ {
__asm__ volatile("cli"); __asm__ volatile("cli");
} }
@@ -29,13 +29,13 @@ AR::CpuFunc::ClearInterruptFlag(VOID)
* @param Registers * @param Registers
* Supplies a pointer to the structure containing all the necessary registers and leafs for CPUID. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers) AR::CpuFunctions::CpuId(IN OUT PCPUID_REGISTERS Registers)
{ {
UINT32 MaxLeaf; UINT32 MaxLeaf;
@@ -76,7 +76,7 @@ AR::CpuFunc::CpuId(IN OUT PCPUID_REGISTERS Registers)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::FlushTlb(VOID) AR::CpuFunctions::FlushTlb(VOID)
{ {
/* Flush the TLB by resetting the CR3 */ /* Flush the TLB by resetting the CR3 */
WriteControlRegister(3, ReadControlRegister(3)); WriteControlRegister(3, ReadControlRegister(3));
@@ -91,7 +91,7 @@ AR::CpuFunc::FlushTlb(VOID)
*/ */
XTCDECL XTCDECL
ULONG ULONG
AR::CpuFunc::GetCpuFlags(VOID) AR::CpuFunctions::GetCpuFlags(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -116,7 +116,7 @@ AR::CpuFunc::GetCpuFlags(VOID)
XTASSEMBLY XTASSEMBLY
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::GetStackPointer(VOID) AR::CpuFunctions::GetStackPointer(VOID)
{ {
/* Get current stack pointer */ /* Get current stack pointer */
__asm__ volatile("mov %%esp, %%eax\n" __asm__ volatile("mov %%esp, %%eax\n"
@@ -135,7 +135,7 @@ AR::CpuFunc::GetStackPointer(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::Halt(VOID) AR::CpuFunctions::Halt(VOID)
{ {
__asm__ volatile("hlt"); __asm__ volatile("hlt");
} }
@@ -149,7 +149,7 @@ AR::CpuFunc::Halt(VOID)
*/ */
XTCDECL XTCDECL
BOOLEAN BOOLEAN
AR::CpuFunc::InterruptsEnabled(VOID) AR::CpuFunctions::InterruptsEnabled(VOID)
{ {
ULONG_PTR Flags; ULONG_PTR Flags;
@@ -172,7 +172,7 @@ AR::CpuFunc::InterruptsEnabled(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::InvalidateTlbEntry(PVOID Address) AR::CpuFunctions::InvalidateTlbEntry(PVOID Address)
{ {
__asm__ volatile("invlpg (%0)" __asm__ volatile("invlpg (%0)"
: :
@@ -192,7 +192,7 @@ AR::CpuFunc::InvalidateTlbEntry(PVOID Address)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source) AR::CpuFunctions::LoadGlobalDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lgdt %0" __asm__ volatile("lgdt %0"
: :
@@ -212,7 +212,7 @@ AR::CpuFunc::LoadGlobalDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source) AR::CpuFunctions::LoadInterruptDescriptorTable(IN PVOID Source)
{ {
__asm__ volatile("lidt %0" __asm__ volatile("lidt %0"
: :
@@ -232,7 +232,7 @@ AR::CpuFunc::LoadInterruptDescriptorTable(IN PVOID Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) AR::CpuFunctions::LoadLocalDescriptorTable(IN USHORT Source)
{ {
__asm__ volatile("lldtw %0" __asm__ volatile("lldtw %0"
: :
@@ -254,8 +254,8 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadSegment(IN USHORT Segment, AR::CpuFunctions::LoadSegment(IN USHORT Segment,
IN ULONG Source) IN ULONG Source)
{ {
switch(Segment) switch(Segment)
{ {
@@ -316,7 +316,7 @@ AR::CpuFunc::LoadSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::LoadTaskRegister(USHORT Source) AR::CpuFunctions::LoadTaskRegister(USHORT Source)
{ {
__asm__ volatile("ltr %0" __asm__ volatile("ltr %0"
: :
@@ -332,7 +332,7 @@ AR::CpuFunc::LoadTaskRegister(USHORT Source)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::MemoryBarrier(VOID) AR::CpuFunctions::MemoryBarrier(VOID)
{ {
LONG Barrier; LONG Barrier;
__asm__ volatile("xchg %%eax, %0" __asm__ volatile("xchg %%eax, %0"
@@ -347,13 +347,13 @@ AR::CpuFunc::MemoryBarrier(VOID)
* @param ControlRegister * @param ControlRegister
* Supplies a number of a control register which controls the general behavior of a CPU. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister) AR::CpuFunctions::ReadControlRegister(IN USHORT ControlRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -404,13 +404,13 @@ AR::CpuFunc::ReadControlRegister(IN USHORT ControlRegister)
* @param DebugRegister * @param DebugRegister
* Supplies a number of a debug register to read from. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONG_PTR ULONG_PTR
AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister) AR::CpuFunctions::ReadDebugRegister(IN USHORT DebugRegister)
{ {
ULONG_PTR Value; ULONG_PTR Value;
@@ -473,13 +473,13 @@ AR::CpuFunc::ReadDebugRegister(IN USHORT DebugRegister)
* @param Offset * @param Offset
* Specifies the offset from the beginning of FS segment. * 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 * @since XT 1.0
*/ */
XTCDECL XTCDECL
ULONG ULONG
AR::CpuFunc::ReadFSDualWord(ULONG Offset) AR::CpuFunctions::ReadFSDualWord(ULONG Offset)
{ {
ULONG Value; ULONG Value;
__asm__ volatile("movl %%fs:%a[Offset], %k[Value]" __asm__ volatile("movl %%fs:%a[Offset], %k[Value]"
@@ -500,7 +500,7 @@ AR::CpuFunc::ReadFSDualWord(ULONG Offset)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register) AR::CpuFunctions::ReadModelSpecificRegister(IN ULONG Register)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -519,7 +519,7 @@ AR::CpuFunc::ReadModelSpecificRegister(IN ULONG Register)
*/ */
XTCDECL XTCDECL
UINT UINT
AR::CpuFunc::ReadMxCsrRegister(VOID) AR::CpuFunctions::ReadMxCsrRegister(VOID)
{ {
return __builtin_ia32_stmxcsr(); return __builtin_ia32_stmxcsr();
} }
@@ -533,7 +533,7 @@ AR::CpuFunc::ReadMxCsrRegister(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadTimeStampCounter(VOID) AR::CpuFunctions::ReadTimeStampCounter(VOID)
{ {
ULONGLONG Value; ULONGLONG Value;
@@ -555,7 +555,7 @@ AR::CpuFunc::ReadTimeStampCounter(VOID)
*/ */
XTCDECL XTCDECL
ULONGLONG ULONGLONG
AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux) AR::CpuFunctions::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
{ {
ULONG Low, High; ULONG Low, High;
@@ -579,7 +579,7 @@ AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::ReadWriteBarrier(VOID) AR::CpuFunctions::ReadWriteBarrier(VOID)
{ {
__asm__ volatile("" __asm__ volatile(""
: :
@@ -596,7 +596,7 @@ AR::CpuFunc::ReadWriteBarrier(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::SetInterruptFlag(VOID) AR::CpuFunctions::SetInterruptFlag(VOID)
{ {
__asm__ volatile("sti"); __asm__ volatile("sti");
} }
@@ -613,7 +613,7 @@ AR::CpuFunc::SetInterruptFlag(VOID)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreGlobalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sgdt %0" __asm__ volatile("sgdt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -633,7 +633,7 @@ AR::CpuFunc::StoreGlobalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreInterruptDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sidt %0" __asm__ volatile("sidt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -653,7 +653,7 @@ AR::CpuFunc::StoreInterruptDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) AR::CpuFunctions::StoreLocalDescriptorTable(OUT PVOID Destination)
{ {
__asm__ volatile("sldt %0" __asm__ volatile("sldt %0"
: "=m" (*(PSHORT)Destination) : "=m" (*(PSHORT)Destination)
@@ -676,8 +676,8 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreSegment(IN USHORT Segment, AR::CpuFunctions::StoreSegment(IN USHORT Segment,
OUT PVOID Destination) OUT PVOID Destination)
{ {
switch(Segment) switch(Segment)
{ {
@@ -723,7 +723,7 @@ AR::CpuFunc::StoreSegment(IN USHORT Segment,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination) AR::CpuFunctions::StoreTaskRegister(OUT PVOID Destination)
{ {
__asm__ volatile("str %0" __asm__ volatile("str %0"
: "=m" (*(PULONG)Destination) : "=m" (*(PULONG)Destination)
@@ -746,8 +746,8 @@ AR::CpuFunc::StoreTaskRegister(OUT PVOID Destination)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister, AR::CpuFunctions::WriteControlRegister(IN USHORT ControlRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified control register */ /* Write a value into specified control register */
switch(ControlRegister) switch(ControlRegister)
@@ -798,8 +798,8 @@ AR::CpuFunc::WriteControlRegister(IN USHORT ControlRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister, AR::CpuFunctions::WriteDebugRegister(IN USHORT DebugRegister,
IN UINT_PTR Value) IN UINT_PTR Value)
{ {
/* Write a value into specified debug register */ /* Write a value into specified debug register */
switch(DebugRegister) switch(DebugRegister)
@@ -867,7 +867,7 @@ AR::CpuFunc::WriteDebugRegister(IN USHORT DebugRegister,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value) AR::CpuFunctions::WriteEflagsRegister(IN UINT_PTR Value)
{ {
__asm__ volatile("push %0\n" __asm__ volatile("push %0\n"
"popf" "popf"
@@ -890,8 +890,8 @@ AR::CpuFunc::WriteEflagsRegister(IN UINT_PTR Value)
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register, AR::CpuFunctions::WriteModelSpecificRegister(IN ULONG Register,
IN ULONGLONG Value) IN ULONGLONG Value)
{ {
__asm__ volatile("wrmsr" __asm__ volatile("wrmsr"
: :
@@ -908,7 +908,7 @@ AR::CpuFunc::WriteModelSpecificRegister(IN ULONG Register,
*/ */
XTCDECL XTCDECL
VOID VOID
AR::CpuFunc::YieldProcessor(VOID) AR::CpuFunctions::YieldProcessor(VOID)
{ {
__asm__ volatile("pause" __asm__ volatile("pause"
: :

View File

@@ -10,31 +10,31 @@
/* Initial kernel boot stack */ /* Initial kernel boot stack */
UCHAR AR::ProcSup::BootStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::BootStack[KERNEL_STACK_SIZE] = {};
/* Double Fault gate */ /* Double Fault gate */
UCHAR AR::ProcSup::DoubleFaultTss[KTSS_IO_MAPS]; UCHAR AR::ProcessorSupport::DoubleFaultTss[KTSS_IO_MAPS];
/* Initial kernel fault stack */ /* Initial kernel fault stack */
UCHAR AR::ProcSup::FaultStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::FaultStack[KERNEL_STACK_SIZE] = {};
/* Initial GDT */ /* Initial GDT */
KGDTENTRY AR::ProcSup::InitialGdt[GDT_ENTRIES] = {}; KGDTENTRY AR::ProcessorSupport::InitialGdt[GDT_ENTRIES] = {};
/* Initial IDT */ /* Initial IDT */
KIDTENTRY AR::ProcSup::InitialIdt[IDT_ENTRIES] = {}; KIDTENTRY AR::ProcessorSupport::InitialIdt[IDT_ENTRIES] = {};
/* Initial Processor Block */ /* Initial Processor Block */
KPROCESSOR_BLOCK AR::ProcSup::InitialProcessorBlock; KPROCESSOR_BLOCK AR::ProcessorSupport::InitialProcessorBlock;
/* Initial TSS */ /* Initial TSS */
KTSS AR::ProcSup::InitialTss; KTSS AR::ProcessorSupport::InitialTss;
/* Initial kernel NMI stack */ /* Initial kernel NMI stack */
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {}; UCHAR AR::ProcessorSupport::NmiStack[KERNEL_STACK_SIZE] = {};
/* NMI task gate */ /* NMI task gate */
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS]; UCHAR AR::ProcessorSupport::NonMaskableInterruptTss[KTSS_IO_MAPS];
/* Unhandled interrupt routine */ /* Unhandled interrupt routine */
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR; PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;

View File

@@ -18,7 +18,7 @@
*/ */
XTAPI XTAPI
PVOID PVOID
AR::ProcSup::GetBootStack(VOID) AR::ProcessorSupport::GetBootStack(VOID)
{ {
/* Return base address of kernel boot stack */ /* Return base address of kernel boot stack */
return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE); return (PVOID)((ULONG_PTR)BootStack + KERNEL_STACK_SIZE);
@@ -26,9 +26,9 @@ AR::ProcSup::GetBootStack(VOID)
XTAPI XTAPI
VOID VOID
AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType, AR::ProcessorSupport::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
OUT PVOID *TrampolineCode, OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize) OUT PULONG_PTR TrampolineSize)
{ {
/* Get trampoline information */ /* Get trampoline information */
switch(TrampolineType) switch(TrampolineType)
@@ -56,7 +56,7 @@ AR::ProcSup::GetTrampolineInformation(IN TRAMPOLINE_TYPE TrampolineType,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessor(VOID) AR::ProcessorSupport::IdentifyProcessor(VOID)
{ {
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
@@ -68,7 +68,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issueing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor in processor control block */
Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx; Prcb->CpuId.Vendor = (CPU_VENDOR)CpuRegisters.Ebx;
@@ -80,7 +80,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU signature in processor control block */ /* Store CPU signature in processor control block */
CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax; CpuSignature = *(PCPUID_SIGNATURE)&CpuRegisters.Eax;
@@ -130,7 +130,7 @@ AR::ProcSup::IdentifyProcessor(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::IdentifyProcessorFeatures(VOID) AR::ProcessorSupport::IdentifyProcessorFeatures(VOID)
{ {
ULONG MaxExtendedLeaf, MaxStandardLeaf; ULONG MaxExtendedLeaf, MaxStandardLeaf;
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
@@ -142,13 +142,13 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get maximum CPUID standard leaf */ /* Get maximum CPUID standard leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
MaxStandardLeaf = CpuRegisters.Eax; MaxStandardLeaf = CpuRegisters.Eax;
/* Get maximum CPUID extended leaf */ /* Get maximum CPUID extended leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX; CpuRegisters.Leaf = CPUID_GET_EXTENDED_MAX;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
MaxExtendedLeaf = CpuRegisters.Eax; MaxExtendedLeaf = CpuRegisters.Eax;
/* Check if CPU supports standard features leaf */ /* Check if CPU supports standard features leaf */
@@ -157,7 +157,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU standard features in processor control block */ /* Store CPU standard features in processor control block */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3; if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SSE3) Prcb->CpuId.FeatureBits |= KCF_SSE3;
@@ -201,7 +201,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU standard features */ /* Get CPU standard features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD7_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU standard7 features in processor control block */ /* Store CPU standard7 features in processor control block */
if(CpuRegisters.Ebx & CPUID_FEATURES_EBX_FSGSBASE) Prcb->CpuId.FeatureBits |= KCF_FSGSBASE; 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 */ /* Get CPU power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT; CpuRegisters.Leaf = CPUID_GET_POWER_MANAGEMENT;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU power management features in processor control block */ /* Store CPU power management features in processor control block */
if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT; if(CpuRegisters.Eax & CPUID_FEATURES_EAX_ARAT) Prcb->CpuId.FeatureBits |= KCF_ARAT;
@@ -231,7 +231,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
/* Get CPU extended features */ /* Get CPU extended features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES; CpuRegisters.Leaf = CPUID_GET_EXTENDED_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Store CPU extended features in processor control block */ /* Store CPU extended features in processor control block */
if(CpuRegisters.Ecx & CPUID_FEATURES_ECX_SVM) Prcb->CpuId.ExtendedFeatureBits |= KCF_SVM; 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 */ /* Get CPU advanced power management features */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_ADVANCED_POWER_MANAGEMENT; 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 */ /* Store CPU advanced power management features in processor control block */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC; if(CpuRegisters.Edx & CPUID_FEATURES_EDX_TSCI) Prcb->CpuId.ExtendedFeatureBits |= KCF_INVARIANT_TSC;
@@ -271,7 +271,7 @@ AR::ProcSup::IdentifyProcessorFeatures(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) AR::ProcessorSupport::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
/* Initialize GDT entries */ /* Initialize GDT entries */
SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); SetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0);
@@ -302,7 +302,7 @@ AR::ProcSup::InitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) AR::ProcessorSupport::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
{ {
UINT Vector; UINT Vector;
@@ -351,7 +351,7 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures) AR::ProcessorSupport::InitializeProcessor(IN PVOID ProcessorStructures)
{ {
KDESCRIPTOR GdtDescriptor, IdtDescriptor; KDESCRIPTOR GdtDescriptor, IdtDescriptor;
PVOID KernelBootStack, KernelFaultStack, KernelNmiStack; PVOID KernelBootStack, KernelFaultStack, KernelNmiStack;
@@ -397,9 +397,9 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1; IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(KIDTENTRY)) - 1;
/* Load GDT, IDT and TSS */ /* Load GDT, IDT and TSS */
AR::CpuFunc::LoadGlobalDescriptorTable(&GdtDescriptor.Limit); AR::CpuFunctions::LoadGlobalDescriptorTable(&GdtDescriptor.Limit);
AR::CpuFunc::LoadInterruptDescriptorTable(&IdtDescriptor.Limit); AR::CpuFunctions::LoadInterruptDescriptorTable(&IdtDescriptor.Limit);
AR::CpuFunc::LoadTaskRegister((UINT)KGDT_SYS_TSS); AR::CpuFunctions::LoadTaskRegister((UINT)KGDT_SYS_TSS);
/* Initialize segment registers */ /* Initialize segment registers */
InitializeSegments(); InitializeSegments();
@@ -432,11 +432,11 @@ AR::ProcSup::InitializeProcessor(IN PVOID ProcessorStructures)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt, IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt, IN PKIDTENTRY Idt,
IN PKTSS Tss, IN PKTSS Tss,
IN PVOID DpcStack) IN PVOID DpcStack)
{ {
/* Set processor block and processor control block */ /* Set processor block and processor control block */
ProcessorBlock->Self = ProcessorBlock; ProcessorBlock->Self = ProcessorBlock;
@@ -478,13 +478,13 @@ AR::ProcSup::InitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorRegisters(VOID) AR::ProcessorSupport::InitializeProcessorRegisters(VOID)
{ {
/* Clear EFLAGS register */ /* Clear EFLAGS register */
AR::CpuFunc::WriteEflagsRegister(0); AR::CpuFunctions::WriteEflagsRegister(0);
/* Enable write-protection */ /* 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 XTAPI
VOID VOID
AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures, AR::ProcessorSupport::InitializeProcessorStructures(IN PVOID ProcessorStructures,
OUT PKGDTENTRY *Gdt, OUT PKGDTENTRY *Gdt,
OUT PKTSS *Tss, OUT PKTSS *Tss,
OUT PKPROCESSOR_BLOCK *ProcessorBlock, OUT PKPROCESSOR_BLOCK *ProcessorBlock,
OUT PVOID *KernelBootStack, OUT PVOID *KernelBootStack,
OUT PVOID *KernelFaultStack, OUT PVOID *KernelFaultStack,
OUT PVOID *KernelNmiStack) OUT PVOID *KernelNmiStack)
{ {
UINT_PTR Address; UINT_PTR Address;
@@ -582,15 +582,15 @@ AR::ProcSup::InitializeProcessorStructures(IN PVOID ProcessorStructures,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeSegments(VOID) AR::ProcessorSupport::InitializeSegments(VOID)
{ {
/* Initialize segments */ /* Initialize segments */
AR::CpuFunc::LoadSegment(SEGMENT_CS, KGDT_R0_CODE); AR::CpuFunctions::LoadSegment(SEGMENT_CS, KGDT_R0_CODE);
AR::CpuFunc::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_DS, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK); AR::CpuFunctions::LoadSegment(SEGMENT_ES, KGDT_R3_DATA | RPL_MASK);
AR::CpuFunc::LoadSegment(SEGMENT_FS, KGDT_R0_PB); AR::CpuFunctions::LoadSegment(SEGMENT_FS, KGDT_R0_PB);
AR::CpuFunc::LoadSegment(SEGMENT_GS, 0); AR::CpuFunctions::LoadSegment(SEGMENT_GS, 0);
AR::CpuFunc::LoadSegment(SEGMENT_SS, KGDT_R0_DATA); AR::CpuFunctions::LoadSegment(SEGMENT_SS, KGDT_R0_DATA);
} }
/** /**
@@ -605,10 +605,10 @@ AR::ProcSup::InitializeSegments(VOID)
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelBootStack, IN PVOID KernelBootStack,
IN PVOID KernelFaultStack, IN PVOID KernelFaultStack,
IN PVOID KernelNmiStack) IN PVOID KernelNmiStack)
{ {
PKGDTENTRY TssEntry; PKGDTENTRY TssEntry;
@@ -644,7 +644,7 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
ProcessorBlock->TssBase->Flags = 0; ProcessorBlock->TssBase->Flags = 0;
/* Set CR3, LDT and SS */ /* 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->LDT = 0;
ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA;
@@ -665,8 +665,8 @@ AR::ProcSup::InitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack) IN PVOID KernelFaultStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -683,7 +683,7 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = 0; Tss->LDT = 0;
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3); Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack; Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack; Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08]; Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x08];
@@ -736,13 +736,13 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt, AR::ProcessorSupport::SetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base, IN ULONG_PTR Base,
IN ULONG Limit, IN ULONG Limit,
IN UCHAR Type, IN UCHAR Type,
IN UCHAR Dpl, IN UCHAR Dpl,
IN UCHAR SegmentMode) IN UCHAR SegmentMode)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
UCHAR Granularity; UCHAR Granularity;
@@ -800,9 +800,9 @@ AR::ProcSup::SetGdtEntry(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt, AR::ProcessorSupport::SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector, IN USHORT Selector,
IN ULONG_PTR Base) IN ULONG_PTR Base)
{ {
PKGDTENTRY GdtEntry; PKGDTENTRY GdtEntry;
@@ -845,13 +845,13 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt, AR::ProcessorSupport::SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector, IN USHORT Vector,
IN PVOID Handler, IN PVOID Handler,
IN USHORT Selector, IN USHORT Selector,
IN USHORT Ist, IN USHORT Ist,
IN USHORT Dpl, IN USHORT Dpl,
IN USHORT Type) IN USHORT Type)
{ {
/* Set the handler's address */ /* Set the handler's address */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
@@ -879,8 +879,8 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
*/ */
XTAPI XTAPI
VOID VOID
AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock, AR::ProcessorSupport::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelNmiStack) IN PVOID KernelNmiStack)
{ {
PKGDTENTRY TaskGateEntry, TssEntry; PKGDTENTRY TaskGateEntry, TssEntry;
PKTSS Tss; PKTSS Tss;
@@ -897,7 +897,7 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
Tss->IoMapBase = sizeof(KTSS); Tss->IoMapBase = sizeof(KTSS);
Tss->Flags = 0; Tss->Flags = 0;
Tss->LDT = 0; Tss->LDT = 0;
Tss->CR3 = AR::CpuFunc::ReadControlRegister(3); Tss->CR3 = AR::CpuFunctions::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelNmiStack; Tss->Esp = (ULONG_PTR)KernelNmiStack;
Tss->Esp0 = (ULONG_PTR)KernelNmiStack; Tss->Esp0 = (ULONG_PTR)KernelNmiStack;
Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02]; Tss->Eip = (ULONG)(ULONG_PTR)ArTrapEntry[0x02];

View File

@@ -26,8 +26,8 @@ AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
PINTERRUPT_HANDLER Handler; PINTERRUPT_HANDLER Handler;
/* Read the handler pointer from the CPU's interrupt dispatch table */ /* Read the handler pointer from the CPU's interrupt dispatch table */
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) + Handler = (PINTERRUPT_HANDLER)AR::CpuFunctions::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER))); (TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
/* Check if the interrupt has a handler registered */ /* Check if the interrupt has a handler registered */
if(Handler != NULLPTR) if(Handler != NULLPTR)

View File

@@ -17,7 +17,7 @@
* *
* @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise. * @return This routine returns TRUE if protection acquired successfully, or FALSE otherwise.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
BOOLEAN BOOLEAN
@@ -65,7 +65,7 @@ EX::Rundown::AcquireProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
@@ -82,7 +82,7 @@ EX::Rundown::CompleteProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
@@ -100,7 +100,7 @@ EX::Rundown::InitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
@@ -117,7 +117,7 @@ EX::Rundown::ReInitializeProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
VOID VOID
@@ -168,7 +168,7 @@ EX::Rundown::ReleaseProtection(IN PEX_RUNDOWN_REFERENCE Descriptor)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
VOID VOID

View File

@@ -50,7 +50,7 @@ HL::Acpi::CacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable)
* @param Rsdp * @param Rsdp
* Supplies a pointer to the memory area, where RSDP virtual address will be stored. * 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 * @since XT 1.0
*/ */
@@ -72,7 +72,7 @@ HL::Acpi::GetAcpiSystemDescriptionPointer(OUT PACPI_RSDP *Rsdp)
* @param AcpiTable * @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored. * 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 * @since XT 1.0
*/ */
@@ -148,7 +148,7 @@ HL::Acpi::GetSystemInformation(OUT PACPI_SYSTEM_INFO *SystemInfo)
/** /**
* Performs an initialization of the ACPI subsystem. * 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 * @since XT 1.0
*/ */
@@ -185,7 +185,7 @@ HL::Acpi::InitializeAcpi(VOID)
/** /**
* Initializes the kernel's local ACPI cache storage. * 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 * @since XT 1.0
*/ */
@@ -220,7 +220,7 @@ HL::Acpi::InitializeAcpiCache(VOID)
* @param AcpiTable * @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored. * 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 * @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. * 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 * @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. * 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 * @since XT 1.0
*/ */
@@ -521,7 +521,7 @@ HL::Acpi::InitializeAcpiSystemStructure(VOID)
/** /**
* Initializes the ACPI Timer. * 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 * @since XT 1.0
*/ */
@@ -568,7 +568,7 @@ HL::Acpi::InitializeAcpiTimer(VOID)
* @param AcpiTable * @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored. * 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 * @since XT 1.0
*/ */
@@ -625,7 +625,7 @@ HL::Acpi::QueryAcpiCache(IN ULONG Signature,
* @param AcpiTable * @param AcpiTable
* Supplies a pointer to memory area where ACPI table virtual address will be stored. * 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 * @since XT 1.0
*/ */

View File

@@ -15,7 +15,7 @@
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */

View File

@@ -36,7 +36,7 @@ HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
KE::RunLevel::RaiseRunLevel(RunLevel); KE::RunLevel::RaiseRunLevel(RunLevel);
/* Enable interrupts */ /* Enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
/** /**
@@ -58,7 +58,7 @@ HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel) IN KRUNLEVEL OldRunLevel)
{ {
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* End system interrupt */ /* End system interrupt */
EndSystemInterrupt(TrapFrame, OldRunLevel); EndSystemInterrupt(TrapFrame, OldRunLevel);
@@ -125,7 +125,7 @@ HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Print debug message and raise kernel panic */ /* Print debug message and raise kernel panic */
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector); 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(); ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */ /* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,
Vector, Vector,
Handler, Handler,
KGDT_R0_CODE, KGDT_R0_CODE,
0, 0,
KIDT_ACCESS_RING0, KIDT_ACCESS_RING0,
AMD64_INTERRUPT_GATE); AMD64_INTERRUPT_GATE);
} }
/** /**

View File

@@ -21,7 +21,7 @@ KRUNLEVEL
HL::RunLevel::GetRunLevel(VOID) HL::RunLevel::GetRunLevel(VOID)
{ {
/* Read current run level */ /* 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) HL::RunLevel::SetRunLevel(IN KRUNLEVEL RunLevel)
{ {
/* Set new run level */ /* Set new run level */
AR::CpuFunc::WriteControlRegister(8, RunLevel); AR::CpuFunctions::WriteControlRegister(8, RunLevel);
} }
/** /**

View File

@@ -24,7 +24,7 @@
* @param Poll * @param Poll
* Indicates whether to only poll, not reading the data. * 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 * @since XT 1.0
*/ */
@@ -98,7 +98,7 @@ HL::ComPort::ReadComPort(IN PCPPORT Port,
* @param Byte * @param Byte
* Value expected from the port. * 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 * @since XT 1.0
*/ */
@@ -144,7 +144,7 @@ HL::ComPort::ReadComPortLsr(IN PCPPORT Port,
* @param BaudRate * @param BaudRate
* Supplies an optional port baud rate. * 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 * @since XT 1.0
*/ */
@@ -240,7 +240,7 @@ HL::ComPort::InitializeComPort(IN OUT PCPPORT Port,
* @param Byte * @param Byte
* Data to be written. * 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 * @since XT 1.0
*/ */

View File

@@ -379,7 +379,7 @@ HL::FrameBuffer::DrawPixel(IN ULONG PositionX,
/** /**
* Enables the Shadow Buffer (Double Buffering) for high-performance rendering. * 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 * @since XT 1.0
*/ */
@@ -452,7 +452,7 @@ HL::FrameBuffer::GetFrameBufferResolution(OUT PULONG Width,
* @param Color * @param Color
* Specifies the color in (A)RGB format. * 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 * @since XT 1.0
*/ */
@@ -476,7 +476,7 @@ HL::FrameBuffer::GetRGBColor(IN ULONG Color)
/** /**
* Initializes frame buffer display. * 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 * @since XT 1.0
*/ */

View File

@@ -15,7 +15,7 @@
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */
@@ -36,7 +36,7 @@ HL::IoPort::ReadPort8(IN USHORT Port)
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */
@@ -57,7 +57,7 @@ HL::IoPort::ReadPort16(IN USHORT Port)
* @param Port * @param Port
* Specifies the address to read from, in the range of 0-0xFFFF. * 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 * @since XT 1.0
*/ */

View File

@@ -37,7 +37,7 @@ HL::Irq::BeginSystemInterrupt(IN KRUNLEVEL RunLevel,
KE::RunLevel::RaiseRunLevel(RunLevel); KE::RunLevel::RaiseRunLevel(RunLevel);
/* Enable interrupts */ /* Enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
/** /**
@@ -59,7 +59,7 @@ HL::Irq::EndInterrupt(IN PKTRAP_FRAME TrapFrame,
IN KRUNLEVEL OldRunLevel) IN KRUNLEVEL OldRunLevel)
{ {
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* End system interrupt */ /* End system interrupt */
EndSystemInterrupt(TrapFrame, OldRunLevel); EndSystemInterrupt(TrapFrame, OldRunLevel);
@@ -126,7 +126,7 @@ HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Print debug message and raise kernel panic */ /* Print debug message and raise kernel panic */
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector); 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(); ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */ /* Update interrupt handler */
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase, AR::ProcessorSupport::SetIdtGate(ProcessorBlock->IdtBase,
Vector, Vector,
Handler, Handler,
KGDT_R0_CODE, KGDT_R0_CODE,
0, 0,
KIDT_ACCESS_RING0, KIDT_ACCESS_RING0,
I686_INTERRUPT_GATE); I686_INTERRUPT_GATE);
} }
/** /**

View File

@@ -99,7 +99,7 @@ HL::Cpu::StartAllProcessors(VOID)
} }
/* Get trampoline information */ /* Get trampoline information */
AR::ProcSup::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize); AR::ProcessorSupport::GetTrampolineInformation(TrampolineApStartup, &TrampolineCode, &TrampolineCodeSize);
/* Verify trampoline information */ /* Verify trampoline information */
if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0) if(TrampolineCode == NULLPTR || TrampolineCodeSize == 0)
@@ -161,8 +161,8 @@ HL::Cpu::StartAllProcessors(VOID)
} }
/* Get ProcessorBlock and Stack address */ /* Get ProcessorBlock and Stack address */
AR::ProcSup::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock, AR::ProcessorSupport::InitializeProcessorStructures(CpuStructures, NULLPTR, NULLPTR, &ProcessorBlock,
&StartBlock->Stack, NULLPTR, NULLPTR); &StartBlock->Stack, NULLPTR, NULLPTR);
/* Set processor number directly in the processor block */ /* Set processor number directly in the processor block */
ProcessorBlock->CpuNumber = CpuNumber; ProcessorBlock->CpuNumber = CpuNumber;
@@ -171,14 +171,15 @@ HL::Cpu::StartAllProcessors(VOID)
KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock); KE::Processor::RegisterProcessorBlock(CpuNumber, ProcessorBlock);
/* Initialize processor start block */ /* Initialize processor start block */
StartBlock->Cr3 = AR::CpuFunc::ReadControlRegister(3); StartBlock->Cr3 = AR::CpuFunctions::ReadControlRegister(3);
StartBlock->Cr4 = AR::CpuFunc::ReadControlRegister(4); StartBlock->Cr4 = AR::CpuFunctions::ReadControlRegister(4);
StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor; StartBlock->EntryPoint = (PVOID)&KE::KernelInit::BootstrapApplicationProcessor;
StartBlock->InitialStack = (PVOID)((ULONG_PTR)StartBlock->Stack - KTHREAD_STACK_OFFSET);
StartBlock->ProcessorStructures = CpuStructures; StartBlock->ProcessorStructures = CpuStructures;
StartBlock->Started = FALSE; StartBlock->Started = FALSE;
/* Memory barrier */ /* Memory barrier */
AR::CpuFunc::MemoryBarrier(); AR::CpuFunctions::MemoryBarrier();
/* Send INIT IPI and wait for 10ms */ /* Send INIT IPI and wait for 10ms */
HL::Pic::SendIpi(SysInfo->CpuInfo[Index].ApicId, 0, APIC_DM_INIT, APIC_DSH_Destination, APIC_TGM_EDGE); 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) while(!StartBlock->Started && Timeout < 100000)
{ {
/* Yield processor and wait for 10us */ /* Yield processor and wait for 10us */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
HL::Timer::StallExecution(10); HL::Timer::StallExecution(10);
Timeout++; Timeout++;
} }

View File

@@ -13,13 +13,16 @@
/** /**
* Allocates, maps and commits a requested system interrupt level internally. * 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 * @param RunLevel
* Supplies the actual system run level to allocate. * Supplies the actual system run level to allocate.
* *
* @param Vector * @param Vector
* Supplies the interrupt handler vector assigned to process requests originating on the line. * 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 * @since XT 1.0
*/ */
@@ -136,7 +139,7 @@ HL::Pic::ClearApicErrors(VOID)
/** /**
* Searches the ACPI MADT tables for the I/O APIC controllers. * 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 * @since XT 1.0
*/ */
@@ -264,7 +267,7 @@ HL::Pic::GetCpuApicId(VOID)
* @param EntryNumber * @param EntryNumber
* Supplies a pointer to the memory area where the entry number will be stored. * 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 * @since XT 1.0
*/ */
@@ -361,11 +364,11 @@ HL::Pic::InitializeApic(VOID)
CpuNumber = KE::Processor::GetCurrentProcessorNumber(); CpuNumber = KE::Processor::GetCurrentProcessorNumber();
/* Enable the APIC */ /* 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.Enable = 1;
BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC); BaseRegister.ExtendedMode = (ApicMode == APIC_MODE_X2APIC);
BaseRegister.BootStrapProcessor = (CpuNumber == 0) ? 1 : 0; 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) */ /* Mask all interrupts by raising Task Priority Register (TPR) */
WriteApicRegister(APIC_TPR, 0xFF); WriteApicRegister(APIC_TPR, 0xFF);
@@ -476,8 +479,8 @@ HL::Pic::InitializeIOApic(VOID)
} }
/* Perform a memory barrier */ /* Perform a memory barrier */
AR::CpuFunc::MemoryBarrier(); AR::CpuFunctions::MemoryBarrier();
AR::CpuFunc::ReadWriteBarrier(); AR::CpuFunctions::ReadWriteBarrier();
/* Read the version register and calculate the maximum number of redirection entries */ /* Read the version register and calculate the maximum number of redirection entries */
VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER); VersionRegister = ReadIOApicRegister(&Controllers[ControllerIndex], IOAPIC_VER);
@@ -636,7 +639,7 @@ HL::Pic::ReadApicRegister(IN APIC_REGISTER Register)
if(ApicMode == APIC_MODE_X2APIC) if(ApicMode == APIC_MODE_X2APIC)
{ {
/* Read from x2APIC MSR */ /* 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 else
{ {
@@ -779,10 +782,10 @@ HL::Pic::SendBroadcastIpi(IN ULONG Vector,
HL::Acpi::GetSystemInformation(&SysInfo); HL::Acpi::GetSystemInformation(&SysInfo);
/* Check whether interrupts are enabled */ /* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled(); Interrupts = AR::CpuFunctions::InterruptsEnabled();
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Iterate over all logical CPUs */ /* Iterate over all logical CPUs */
for(Index = 0; Index < SysInfo->CpuCount; Index++) for(Index = 0; Index < SysInfo->CpuCount; Index++)
@@ -815,7 +818,7 @@ HL::Pic::SendBroadcastIpi(IN ULONG Vector,
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
} }
@@ -868,10 +871,10 @@ HL::Pic::SendIpi(IN ULONG ApicId,
BOOLEAN Interrupts; BOOLEAN Interrupts;
/* Check whether interrupts are enabled */ /* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled(); Interrupts = AR::CpuFunctions::InterruptsEnabled();
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Check current APIC mode and destination */ /* Check current APIC mode and destination */
if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self) if(ApicMode == APIC_MODE_X2APIC && DestinationShortHand == APIC_DSH_Self)
@@ -883,7 +886,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
if(Interrupts) if(Interrupts)
{ {
/* Check whether interrupts need to be re-enabled */ /* Check whether interrupts need to be re-enabled */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
/* Nothing more to do */ /* Nothing more to do */
@@ -914,7 +917,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0) while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
{ {
/* Yield the processor */ /* Yield the processor */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
/* In xAPIC compatibility mode, write the command to the ICR registers */ /* 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) while((ReadApicRegister((APIC_REGISTER)(APIC_IRR + (Vector / 32))) & (1UL << (Vector % 32))) == 0)
{ {
/* Yield the processor */ /* Yield the processor */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
} }
} }
@@ -937,7 +940,7 @@ HL::Pic::SendIpi(IN ULONG ApicId,
if(Interrupts) if(Interrupts)
{ {
/* Re-enable 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) if(ApicMode == APIC_MODE_X2APIC)
{ {
/* Write to x2APIC MSR */ /* 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 else
{ {

View File

@@ -15,7 +15,7 @@
* @param Time * @param Time
* Supplies a pointer to a structure to receive the system 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 * @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) while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
{ {
/* Yield the processor */ /* Yield the processor */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
/* Latch the first sequential hardware time snapshot */ /* 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) while(HL::Firmware::ReadCmosRegister(CMOS_REGISTER_A) & CMOS_REGISTER_A_UPDATE_IN_PROGRESS)
{ {
/* Yield the processor */ /* Yield the processor */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
/* Latch the second sequential hardware time snapshot for verification */ /* Latch the second sequential hardware time snapshot for verification */
@@ -192,7 +192,7 @@ HL::Rtc::GetRealTimeClock(OUT PTIME_FIELDS Time)
* @param Time * @param Time
* Supplies a pointer to a structure with populated data and 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 * @since XT 1.0
*/ */

View File

@@ -12,7 +12,7 @@
/** /**
* Calibrates the Local APIC timer frequency. * 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 * @since XT 1.0
*/ */
@@ -84,13 +84,13 @@ HL::Timer::CalibrateTscCounter(VOID)
} }
/* Latch the initial TSC value */ /* Latch the initial TSC value */
InitialTickCount = AR::CpuFunc::ReadTimeStampCounterProcessor(&TscAux); InitialTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);
/* Stall CPU execution for exactly 10 milliseconds */ /* Stall CPU execution for exactly 10 milliseconds */
StallExecution(10000); StallExecution(10000);
/* Read current tick count from TSC */ /* Read current tick count from TSC */
FinalTickCount = AR::CpuFunc::ReadTimeStampCounterProcessor(&TscAux); FinalTickCount = AR::CpuFunctions::ReadTimeStampCounterProcessor(&TscAux);
/* Calculate the elapsed ticks over the 10ms window */ /* Calculate the elapsed ticks over the 10ms window */
return (FinalTickCount - InitialTickCount) * 100; return (FinalTickCount - InitialTickCount) * 100;
@@ -104,6 +104,10 @@ HL::Timer::CalibrateTscCounter(VOID)
* *
* @param HardwareDivider * @param HardwareDivider
* Supplies the programmed threshold/divider for the interrupt generation. * Supplies the programmed threshold/divider for the interrupt generation.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/ */
XTAPI XTAPI
VOID 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 * Initializes the High Precision Event Timer (HPET) by discovering its ACPI configuration and mapping
* its hardware registers into the kernel's virtual address space. * 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 * @since XT 1.0
*/ */
@@ -388,7 +392,7 @@ HL::Timer::InitializeApicTimer(VOID)
/** /**
* Initializes the High Precision Event Timer (HPET) Timer. * 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 * @since XT 1.0
*/ */
@@ -443,10 +447,41 @@ HL::Timer::InitializeHpetTimer(VOID)
return STATUS_SUCCESS; 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). * 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 * @since XT 1.0
*/ */
@@ -911,7 +946,7 @@ HL::Timer::QueryPerformanceCounterTsc(VOID)
ULONG TscAux; ULONG TscAux;
/* Retrieve the timestamp */ /* 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 */ /* Query maximum standard CPUID leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
MaxStandardLeaf = CpuRegisters.Eax; MaxStandardLeaf = CpuRegisters.Eax;
/* Check Always Running Timer - ART if leaf supported */ /* 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 */ /* Query the Time Stamp Counter and Core Crystal Clock information CPUID leaf */
RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RTL::Memory::ZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK; CpuRegisters.Leaf = CPUID_GET_TSC_CRYSTAL_CLOCK;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Verify Always Running Timer support */ /* Verify Always Running Timer support */
if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0) if(CpuRegisters.Eax != 0 && CpuRegisters.Ebx != 0)
@@ -1047,10 +1082,10 @@ HL::Timer::SetClockRateApic(ULONG Rate)
} }
/* Check whether interrupts are enabled */ /* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled(); Interrupts = AR::CpuFunctions::InterruptsEnabled();
/* Disable interrupts */ /* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Commit the new divider to the TICR register */ /* Commit the new divider to the TICR register */
HL::Pic::WriteApicRegister(APIC_TICR, NewDivider); HL::Pic::WriteApicRegister(APIC_TICR, NewDivider);
@@ -1062,7 +1097,7 @@ HL::Timer::SetClockRateApic(ULONG Rate)
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
/* Return the actual clock rate set */ /* Return the actual clock rate set */
@@ -1174,7 +1209,7 @@ HL::Timer::StallExecutionAcpiPm(IN ULONG MicroSeconds)
StartTick = CurrentTick; StartTick = CurrentTick;
/* Issue a PAUSE instruction to relieve memory bus contention */ /* 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) while((Hpet->MainCounterValue - StartTick) < TargetTicks)
{ {
/* Issue a PAUSE instruction to relieve memory bus contention */ /* 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 */ /* Calculate target ticks based on calibrated TSC frequency */
TargetTicks = ((ULONGLONG)MicroSeconds * PerformanceFrequency) / 1000000ULL; TargetTicks = ((ULONGLONG)MicroSeconds * PerformanceFrequency) / 1000000ULL;
StartTick = AR::CpuFunc::ReadTimeStampCounter(); StartTick = AR::CpuFunctions::ReadTimeStampCounter();
/* Spin until the elapsed ticks reach the target */ /* 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 */ /* Issue a PAUSE instruction to relieve memory bus contention */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
} }

View File

@@ -15,7 +15,7 @@
/* Architecture-specific Library */ /* Architecture-specific Library */
namespace AR namespace AR
{ {
class CpuFunc class CpuFunctions
{ {
public: public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID); STATIC XTCDECL VOID ClearInterruptFlag(VOID);

View File

@@ -15,7 +15,7 @@
/* Architecture-specific Library */ /* Architecture-specific Library */
namespace AR namespace AR
{ {
class ProcSup class ProcessorSupport
{ {
private: private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE]; STATIC UCHAR BootStack[KERNEL_STACK_SIZE];

View File

@@ -15,7 +15,7 @@
/* Architecture-specific Library */ /* Architecture-specific Library */
namespace AR namespace AR
{ {
class CpuFunc class CpuFunctions
{ {
public: public:
STATIC XTCDECL VOID ClearInterruptFlag(VOID); STATIC XTCDECL VOID ClearInterruptFlag(VOID);

View File

@@ -15,7 +15,7 @@
/* Architecture-specific Library */ /* Architecture-specific Library */
namespace AR namespace AR
{ {
class ProcSup class ProcessorSupport
{ {
private: private:
STATIC UCHAR BootStack[KERNEL_STACK_SIZE]; STATIC UCHAR BootStack[KERNEL_STACK_SIZE];

View File

@@ -38,6 +38,7 @@ namespace HL
STATIC TIMER_TYPE TimerType; STATIC TIMER_TYPE TimerType;
public: public:
STATIC XTAPI VOID InitializeLocalClock(VOID);
STATIC XTAPI VOID InitializeTimer(VOID); STATIC XTAPI VOID InitializeTimer(VOID);
STATIC XTAPI LARGE_INTEGER QueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency); STATIC XTAPI LARGE_INTEGER QueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceFrequency);
STATIC XTAPI ULONG SetClockRate(IN ULONG Rate); STATIC XTAPI ULONG SetClockRate(IN ULONG Rate);

View File

@@ -30,7 +30,6 @@ namespace MM
STATIC SIZE_T BigAllocationsTrackingTableHash; STATIC SIZE_T BigAllocationsTrackingTableHash;
STATIC KSPIN_LOCK BigAllocationsTrackingTableLock; STATIC KSPIN_LOCK BigAllocationsTrackingTableLock;
STATIC SIZE_T BigAllocationsTrackingTableSize; STATIC SIZE_T BigAllocationsTrackingTableSize;
STATIC PPOOL_TRACKING_TABLE TagTables[MM_POOL_TRACKING_TABLES];
public: public:
STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType, STATIC XTAPI XTSTATUS AllocatePages(IN MMPOOL_TYPE PoolType,
@@ -65,6 +64,7 @@ namespace MM
OUT PPFN_NUMBER PagesFreed); OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress, STATIC XTAPI XTSTATUS FreePagedPoolPages(IN PVOID VirtualAddress,
OUT PPFN_NUMBER PagesFreed); OUT PPFN_NUMBER PagesFreed);
STATIC XTAPI VOID PopulateAllocationTags(VOID);
STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag, STATIC XTAPI VOID RegisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes, IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType); IN MMPOOL_TYPE PoolType);

View File

@@ -21,6 +21,7 @@
#include <rtl/llist.hh> #include <rtl/llist.hh>
#include <rtl/math.hh> #include <rtl/math.hh>
#include <rtl/memory.hh> #include <rtl/memory.hh>
#include <rtl/rbtree.hh>
#include <rtl/sha1.hh> #include <rtl/sha1.hh>
#include <rtl/slist.hh> #include <rtl/slist.hh>
#include <rtl/string.hh> #include <rtl/string.hh>

View 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 */

View File

@@ -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. * 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 * @since XT 1.0
*/ */
@@ -211,7 +211,7 @@ KD::DebugIo::DetectDebugPorts(VOID)
/** /**
* Initializes the kernel's debugger I/O providers. * 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 * @since XT 1.0
*/ */
@@ -249,7 +249,7 @@ KD::DebugIo::InitializeDebugIoProviders(VOID)
/** /**
* Initializes the framebuffer device provider for the kernel debugger. * 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 * @since XT 1.0
*/ */
@@ -288,7 +288,7 @@ KD::DebugIo::InitializeFrameBufferProvider(VOID)
/** /**
* Initializes the serial port device provider for the kernel debugger. * 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 * @since XT 1.0
*/ */
@@ -376,7 +376,7 @@ KD::DebugIo::SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine)
* @param Character * @param Character
* The integer promotion of the character to be written. * 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 * @since XT 1.0
*/ */

View File

@@ -25,10 +25,13 @@ XTAPI
VOID VOID
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
{ {
PKPROCESSOR_BLOCK ProcessorBlock; PKPROCESSOR_CONTROL_BLOCK ControlBlock;
/* Initialize application CPU */ /* Initialize application CPU */
AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures); AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
/* Get processor control block */
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
/* Initialize processor */ /* Initialize processor */
HL::Cpu::InitializeProcessor(); HL::Cpu::InitializeProcessor();
@@ -39,12 +42,24 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
/* Mark processor as started */ /* Mark processor as started */
StartBlock->Started = TRUE; StartBlock->Started = TRUE;
/* Get current processor block */ /* Initialize CPU power state structures */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); 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 */ /* Enter infinite loop */
DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n", DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n",
ProcessorBlock->CpuNumber); ControlBlock->CpuNumber);
KE::Crash::HaltSystem(); KE::Crash::HaltSystem();
} }
@@ -96,7 +111,7 @@ KE::KernelInit::BootstrapKernel(VOID)
/* Initialize Idle thread */ /* Initialize Idle thread */
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; CurrentThread->State = Running;
@@ -185,7 +200,7 @@ KE::KernelInit::SwitchBootStack(VOID)
PVOID StartKernel; PVOID StartKernel;
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ /* 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() */ /* Get address of KernelInit::StartKernel() */
StartKernel = (PVOID)KE::KernelInit::BootstrapKernel; StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;
@@ -198,7 +213,6 @@ KE::KernelInit::SwitchBootStack(VOID)
: :
: [Stack] "r" (Stack), : [Stack] "r" (Stack),
[TargetRoutine] "r" (StartKernel), [TargetRoutine] "r" (StartKernel),
[TotalSize] "i" (FLOATING_SAVE_AREA_SIZE + KEXCEPTION_FRAME_SIZE + [TotalSize] "i" (KTHREAD_STACK_OFFSET)
KSWITCH_FRAME_SIZE + KRETURN_ADDRESS_SIZE)
: "memory", "rbp", "rsp"); : "memory", "rbp", "rsp");
} }

View File

@@ -21,7 +21,7 @@ PKPROCESSOR_BLOCK
KE::Processor::GetCurrentProcessorBlock(VOID) KE::Processor::GetCurrentProcessorBlock(VOID)
{ {
/* Get processor block from GS register */ /* 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 PKPROCESSOR_CONTROL_BLOCK
KE::Processor::GetCurrentProcessorControlBlock(VOID) 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 ULONG
KE::Processor::GetCurrentProcessorNumber(VOID) 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 PKTHREAD
KE::Processor::GetCurrentThread(VOID) 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) KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{ {
/* Save CR registers */ /* Save CR registers */
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);
CpuState->SpecialRegisters.Cr8 = AR::CpuFunc::ReadControlRegister(8); CpuState->SpecialRegisters.Cr8 = AR::CpuFunctions::ReadControlRegister(8);
/* Save DR registers */ /* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);
/* Save MSR registers */ /* Save MSR registers */
CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_GSBASE); CpuState->SpecialRegisters.MsrGsBase = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_GSBASE);
CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); CpuState->SpecialRegisters.MsrGsSwap = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE);
CpuState->SpecialRegisters.MsrCStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_CSTAR); CpuState->SpecialRegisters.MsrCStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_CSTAR);
CpuState->SpecialRegisters.MsrLStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_LSTAR); CpuState->SpecialRegisters.MsrLStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_LSTAR);
CpuState->SpecialRegisters.MsrStar = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_STAR); CpuState->SpecialRegisters.MsrStar = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_STAR);
CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunc::ReadModelSpecificRegister(X86_MSR_FMASK); CpuState->SpecialRegisters.MsrSyscallMask = AR::CpuFunctions::ReadModelSpecificRegister(X86_MSR_FMASK);
/* Save XMM control/status register */ /* Save XMM control/status register */
CpuState->SpecialRegisters.MxCsr = AR::CpuFunc::ReadMxCsrRegister(); CpuState->SpecialRegisters.MxCsr = AR::CpuFunctions::ReadMxCsrRegister();
/* Save GDT, IDT, LDT and TaskRegister */ /* Save GDT, IDT, LDT and TaskRegister */
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
} }

View File

@@ -38,7 +38,7 @@
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID

View File

@@ -46,7 +46,7 @@ KE::BootInformation::GetFirmwareType(VOID)
* @param Parameter * @param Parameter
* Supplies a pointer to a variable that receives a pointer to the matching parameter, or NULLPTR if not found. * 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 * @since XT 1.0
*/ */
@@ -116,7 +116,7 @@ KE::BootInformation::GetKernelParameter(IN PCWSTR ParameterName,
* @param BufferSize * @param BufferSize
* Supplies the size of the value buffer, in wide characters. * 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 * @since XT 1.0
*/ */

View File

@@ -24,8 +24,8 @@ KE::Crash::HaltSystem(VOID)
for(;;) for(;;)
{ {
/* Halt system */ /* Halt system */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
AR::CpuFunc::Halt(); AR::CpuFunctions::Halt();
} }
} }

View File

@@ -23,7 +23,7 @@
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -56,7 +56,7 @@ KE::Dpc::InitializeDpc(IN PKDPC Dpc,
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.2 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -86,7 +86,7 @@ KE::Dpc::InitializeThreadedDpc(IN PKDPC Dpc,
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 4.0 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -104,7 +104,7 @@ KE::Dpc::SetTargetProcessor(IN PKDPC Dpc,
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.2 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID 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. * @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 XTAPI
BOOLEAN BOOLEAN

View File

@@ -17,7 +17,7 @@
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -41,7 +41,7 @@ KE::Event::ClearEvent(IN PKEVENT Event)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -71,7 +71,7 @@ KE::Event::InitializeEvent(OUT PKEVENT Event,
* *
* @return This routine returns the previous signal state of the event. * @return This routine returns the previous signal state of the event.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
LONG LONG

View File

@@ -25,10 +25,13 @@ XTAPI
VOID VOID
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
{ {
PKPROCESSOR_BLOCK ProcessorBlock; PKPROCESSOR_CONTROL_BLOCK ControlBlock;
/* Initialize application CPU */ /* Initialize application CPU */
AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures); AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
/* Get processor control block */
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
/* Initialize processor */ /* Initialize processor */
HL::Cpu::InitializeProcessor(); HL::Cpu::InitializeProcessor();
@@ -39,12 +42,24 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
/* Mark processor as started */ /* Mark processor as started */
StartBlock->Started = TRUE; StartBlock->Started = TRUE;
/* Get current processor block */ /* Initialize CPU power state structures */
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); 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 */ /* Enter infinite loop */
DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n", DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n",
ProcessorBlock->CpuNumber); ControlBlock->CpuNumber);
KE::Crash::HaltSystem(); KE::Crash::HaltSystem();
} }
@@ -96,7 +111,7 @@ KE::KernelInit::BootstrapKernel(VOID)
/* Initialize Idle thread */ /* Initialize Idle thread */
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, 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->NextProcessor = Prcb->CpuNumber;
CurrentThread->Priority = THREAD_HIGH_PRIORITY; CurrentThread->Priority = THREAD_HIGH_PRIORITY;
CurrentThread->State = Running; CurrentThread->State = Running;
@@ -185,7 +200,7 @@ KE::KernelInit::SwitchBootStack(VOID)
PVOID StartKernel; PVOID StartKernel;
/* Calculate the stack pointer at the top of the buffer, ensuring it is properly aligned as required by the ABI */ /* 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() */ /* Get address of KernelInit::StartKernel() */
StartKernel = (PVOID)KE::KernelInit::BootstrapKernel; StartKernel = (PVOID)KE::KernelInit::BootstrapKernel;
@@ -200,6 +215,6 @@ KE::KernelInit::SwitchBootStack(VOID)
: [Cr0Value] "i" (CR0_EM | CR0_MP | CR0_TS), : [Cr0Value] "i" (CR0_EM | CR0_MP | CR0_TS),
[Stack] "r" (Stack), [Stack] "r" (Stack),
[TargetRoutine] "r" (StartKernel), [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"); : "ebp", "esp", "memory");
} }

View File

@@ -43,7 +43,7 @@ KE::KThread::InitializeThreadContext(IN PKTHREAD Thread,
PFX_SAVE_FORMAT FxSaveFormat; PFX_SAVE_FORMAT FxSaveFormat;
/* Set initial thread frame */ /* 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 */ /* Fill floating point save area with zeroes */
RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA)); RTL::Memory::ZeroMemory(&ThreadFrame->NpxFrame, sizeof(FX_SAVE_AREA));

View File

@@ -21,7 +21,7 @@ PKPROCESSOR_BLOCK
KE::Processor::GetCurrentProcessorBlock(VOID) KE::Processor::GetCurrentProcessorBlock(VOID)
{ {
/* Get processor block from FS register */ /* 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 PKPROCESSOR_CONTROL_BLOCK
KE::Processor::GetCurrentProcessorControlBlock(VOID) 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 ULONG
KE::Processor::GetCurrentProcessorNumber(VOID) 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 PKTHREAD
KE::Processor::GetCurrentThread(VOID) 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) KE::Processor::SaveProcessorState(OUT PKPROCESSOR_STATE CpuState)
{ {
/* Save CR registers */ /* Save CR registers */
CpuState->SpecialRegisters.Cr0 = AR::CpuFunc::ReadControlRegister(0); CpuState->SpecialRegisters.Cr0 = AR::CpuFunctions::ReadControlRegister(0);
CpuState->SpecialRegisters.Cr2 = AR::CpuFunc::ReadControlRegister(2); CpuState->SpecialRegisters.Cr2 = AR::CpuFunctions::ReadControlRegister(2);
CpuState->SpecialRegisters.Cr3 = AR::CpuFunc::ReadControlRegister(3); CpuState->SpecialRegisters.Cr3 = AR::CpuFunctions::ReadControlRegister(3);
CpuState->SpecialRegisters.Cr4 = AR::CpuFunc::ReadControlRegister(4); CpuState->SpecialRegisters.Cr4 = AR::CpuFunctions::ReadControlRegister(4);
/* Save DR registers */ /* Save DR registers */
CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunc::ReadDebugRegister(0); CpuState->SpecialRegisters.KernelDr0 = AR::CpuFunctions::ReadDebugRegister(0);
CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunc::ReadDebugRegister(1); CpuState->SpecialRegisters.KernelDr1 = AR::CpuFunctions::ReadDebugRegister(1);
CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunc::ReadDebugRegister(2); CpuState->SpecialRegisters.KernelDr2 = AR::CpuFunctions::ReadDebugRegister(2);
CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunc::ReadDebugRegister(3); CpuState->SpecialRegisters.KernelDr3 = AR::CpuFunctions::ReadDebugRegister(3);
CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunc::ReadDebugRegister(6); CpuState->SpecialRegisters.KernelDr6 = AR::CpuFunctions::ReadDebugRegister(6);
CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunc::ReadDebugRegister(7); CpuState->SpecialRegisters.KernelDr7 = AR::CpuFunctions::ReadDebugRegister(7);
/* Save GDT, IDT, LDT and TaskRegister */ /* Save GDT, IDT, LDT and TaskRegister */
AR::CpuFunc::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); AR::CpuFunctions::StoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit);
AR::CpuFunc::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); AR::CpuFunctions::StoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit);
AR::CpuFunc::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); AR::CpuFunctions::StoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr);
AR::CpuFunc::StoreTaskRegister(&CpuState->SpecialRegisters.Tr); AR::CpuFunctions::StoreTaskRegister(&CpuState->SpecialRegisters.Tr);
} }

View File

@@ -9,6 +9,13 @@
#include <xtos.hh> #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 XTAPI
PEPROCESS PEPROCESS
KE::KProcess::GetInitialProcess(VOID) KE::KProcess::GetInitialProcess(VOID)
@@ -36,7 +43,7 @@ KE::KProcess::GetInitialProcess(VOID)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID

View File

@@ -47,7 +47,7 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
} }
/* Initialize boot CPU and set the unhandled interrupt routine */ /* Initialize boot CPU and set the unhandled interrupt routine */
AR::ProcSup::InitializeProcessor(NULLPTR); AR::ProcessorSupport::InitializeProcessor(NULLPTR);
AR::Traps::SetUnhandledInterruptRoutine(HL::Irq::HandleUnexpectedInterrupt); AR::Traps::SetUnhandledInterruptRoutine(HL::Irq::HandleUnexpectedInterrupt);
/* Initialize system resources */ /* Initialize system resources */

View File

@@ -9,6 +9,13 @@
#include <xtos.hh> #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 XTAPI
PETHREAD PETHREAD
KE::KThread::GetInitialThread(VOID) KE::KThread::GetInitialThread(VOID)
@@ -43,9 +50,9 @@ KE::KThread::GetInitialThread(VOID)
* @param Stack * @param Stack
* Supplies a pointer to the stack of the thread. * 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 XTAPI
XTSTATUS XTSTATUS
@@ -189,7 +196,7 @@ KE::KThread::InitializeThread(IN PKPROCESS Process,
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID

View File

@@ -23,7 +23,7 @@
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -75,7 +75,7 @@ KE::Semaphore::ReadState(IN PKSEMAPHORE Semaphore)
* *
* @return This routine returns a previous signal state of the semaphore. * @return This routine returns a previous signal state of the semaphore.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
LONG LONG

View File

@@ -49,12 +49,12 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
while(*(VOLATILE PKSPIN_LOCK)SpinLock & 1) while(*(VOLATILE PKSPIN_LOCK)SpinLock & 1)
{ {
/* Yield processor and keep waiting */ /* Yield processor and keep waiting */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
} }
} }
/* Add an explicit memory barrier */ /* 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. * @return This routine does not return any value.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -183,7 +183,7 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
RTL::Atomic::And32((PLONG)SpinLock, 0); RTL::Atomic::And32((PLONG)SpinLock, 0);
/* Add an explicit memory barrier */ /* Add an explicit memory barrier */
AR::CpuFunc::ReadWriteBarrier(); AR::CpuFunctions::ReadWriteBarrier();
} }
/** /**
@@ -204,7 +204,7 @@ TestSpinLock(IN PKSPIN_LOCK SpinLock)
if(*SpinLock) if(*SpinLock)
{ {
/* Spinlock is busy, yield processor and return FALSE */ /* Spinlock is busy, yield processor and return FALSE */
AR::CpuFunc::YieldProcessor(); AR::CpuFunctions::YieldProcessor();
return FALSE; return FALSE;
} }

View File

@@ -18,7 +18,7 @@
* @param ResourceHeader * @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored. * 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 * @since XT 1.0
*/ */
@@ -62,10 +62,10 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
/* Check if interrupts are enabled */ /* Check if interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled(); Interrupts = AR::CpuFunctions::InterruptsEnabled();
/* Disable interrupts and acquire a spinlock */ /* Disable interrupts and acquire a spinlock */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::SpinLock::AcquireSpinLock(&ResourcesLock); KE::SpinLock::AcquireSpinLock(&ResourcesLock);
/* Iterate through system resources list */ /* Iterate through system resources list */
@@ -114,7 +114,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
/* Return resource header and status code */ /* Return resource header and status code */
@@ -131,7 +131,7 @@ KE::SystemResources::GetSystemResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
* @param ResourceHeader * @param ResourceHeader
* Specifies a memory area where a pointer to the system resource header will be stored. * 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 * @since XT 1.0
*/ */
@@ -147,7 +147,7 @@ KE::SystemResources::GetResource(IN SYSTEM_RESOURCE_TYPE ResourceType,
/** /**
* Initializes system resource management. * 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 * @since XT 1.0
*/ */
@@ -220,7 +220,7 @@ VOID
KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader) KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
{ {
/* Disable interrupts and acquire a spinlock */ /* Disable interrupts and acquire a spinlock */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::SpinLock::AcquireSpinLock(&ResourcesLock); KE::SpinLock::AcquireSpinLock(&ResourcesLock);
/* Release resource lock */ /* Release resource lock */
@@ -228,5 +228,5 @@ KE::SystemResources::ReleaseResource(IN PSYSTEM_RESOURCE_HEADER ResourceHeader)
/* Release spinlock and enable interrupts */ /* Release spinlock and enable interrupts */
KE::SpinLock::ReleaseSpinLock(&ResourcesLock); KE::SpinLock::ReleaseSpinLock(&ResourcesLock);
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }

View File

@@ -17,7 +17,7 @@
* *
* @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise. * @return This routine returns TRUE if the cancelled timer was set, or FALSE otherwise.
* *
* @since NT 3.5 * @since XT 1.0
*/ */
XTAPI XTAPI
BOOLEAN BOOLEAN
@@ -57,7 +57,7 @@ KE::Timer::CancelTimer(IN PKTIMER Timer)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 4.0 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID

View File

@@ -18,7 +18,7 @@
* @param Memory * @param Memory
* Supplies a pointer to the allocated pool of pages. * 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 * @since XT 1.0
*/ */
@@ -192,7 +192,7 @@ MM::Allocator::AllocateNonPagedPoolPages(IN PFN_COUNT Pages,
* @param Memory * @param Memory
* Supplies a pointer to the allocated pool of pages. * 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 * @since XT 1.0
*/ */
@@ -219,7 +219,7 @@ MM::Allocator::AllocatePagedPoolPages(IN PFN_COUNT Pages,
* @param Memory * @param Memory
* Supplies a pointer to the allocated pool of pages. * 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 * @since XT 1.0
*/ */
@@ -271,7 +271,7 @@ MM::Allocator::AllocatePages(IN MMPOOL_TYPE PoolType,
* @param Memory * @param Memory
* Supplies a pointer to the allocated 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 * @since XT 1.0
*/ */
@@ -300,7 +300,7 @@ MM::Allocator::AllocatePool(IN MMPOOL_TYPE PoolType,
* @param Tag * @param Tag
* Specifies the allocation identifying 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 * @since XT 1.0
*/ */
@@ -722,7 +722,7 @@ MM::Allocator::ExpandBigAllocationsTable(VOID)
/* Update the pool tracking statistics */ /* Update the pool tracking statistics */
UnregisterAllocationTag(SIGNATURE32('M', 'M', 'g', 'r'), PagesFreed << MM_PAGE_SHIFT, (MMPOOL_TYPE)0); 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 success */
return TRUE; return TRUE;
@@ -737,7 +737,7 @@ MM::Allocator::ExpandBigAllocationsTable(VOID)
* @param PagesFreed * @param PagesFreed
* Supplies a pointer to a variable that will receive the number of pages freed. * 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 * @since XT 1.0
*/ */
@@ -985,7 +985,7 @@ MM::Allocator::FreeNonPagedPoolPages(IN PVOID VirtualAddress,
* @param PagesFreed * @param PagesFreed
* Supplies a pointer to a variable that will receive the number of pages freed. * 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 * @since XT 1.0
*/ */
@@ -1006,7 +1006,7 @@ MM::Allocator::FreePagedPoolPages(IN PVOID VirtualAddress,
* @param VirtualAddress * @param VirtualAddress
* Supplies the base virtual address of the pages allocation to free. * 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 * @since XT 1.0
*/ */
@@ -1026,7 +1026,7 @@ MM::Allocator::FreePages(IN PVOID VirtualAddress)
* @param PagesFreed * @param PagesFreed
* Supplies a pointer to a variable that will receive the number of pages freed. * 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 * @since XT 1.0
*/ */
@@ -1059,7 +1059,7 @@ MM::Allocator::FreePages(IN PVOID VirtualAddress,
* @param VirtualAddress * @param VirtualAddress
* Supplies the base virtual address of the pool allocation to free. * 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 * @since XT 1.0
*/ */
@@ -1080,7 +1080,7 @@ MM::Allocator::FreePool(IN PVOID VirtualAddress)
* @param Tag * @param Tag
* Specifies the allocation identifying 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 * @since XT 1.0
*/ */
@@ -1379,12 +1379,12 @@ MM::Allocator::InitializeAllocationsTracking(VOID)
/* Zero the entire memory used by the table */ /* Zero the entire memory used by the table */
RtlZeroMemory(AllocationsTrackingTable, AllocationsTrackingTableSize * sizeof(POOL_TRACKING_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 */ /* Calculate and store the hash mask */
AllocationsTrackingTableMask = AllocationsTrackingTableSize - 2; 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 */ /* Initialize the spinlock used to synchronize concurrent modifications to the tracking table */
KE::SpinLock::InitializeSpinLock(&AllocationsTrackingTableLock); KE::SpinLock::InitializeSpinLock(&AllocationsTrackingTableLock);
} }
@@ -1505,6 +1505,64 @@ MM::Allocator::InitializeBigAllocationsTracking(VOID)
NonPagedPool); 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. * Registers a pool memory allocation in the tracking table.
* *
@@ -1527,12 +1585,8 @@ MM::Allocator::RegisterAllocationTag(IN ULONG Tag,
IN SIZE_T Bytes, IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType) IN MMPOOL_TYPE PoolType)
{ {
PPOOL_TRACKING_TABLE CpuTable, TableEntry; PPOOL_TRACKING_TABLE TableEntry;
ULONG Hash, Index, Processor; ULONG Hash, Index;
/* Retrieve the local tracking table for the current processor */
Processor = KE::Processor::GetCurrentProcessorNumber();
CpuTable = TagTables[Processor];
/* Strip the protected pool bit */ /* Strip the protected pool bit */
Tag &= ~MM_POOL_PROTECTED; 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 */ /* Probe the tracking table until a match or an empty slot is found */
do do
{ {
/* Fetch the tracker entry from the CPU table */ /* Fetch the tracker entry from the table */
TableEntry = &CpuTable[Hash]; TableEntry = &AllocationsTrackingTable[Hash];
/* Check if the current entry tracks the requested pool tag */ /* Check if the current entry tracks the requested pool tag */
if(TableEntry->Tag == Tag) if(TableEntry->Tag == Tag)
@@ -1568,34 +1622,21 @@ MM::Allocator::RegisterAllocationTag(IN ULONG Tag,
return; return;
} }
/* Check if the CPU table is entirely empty */ /* Check if the table is entirely empty */
if(TableEntry->Tag == 0) 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 */ /* Check if this is not the designated overflow bucket */
if(Hash != (AllocationsTrackingTableSize - 1)) 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 */ /* Perform a double-checked lock */
if(AllocationsTrackingTable[Hash].Tag == 0) if(AllocationsTrackingTable[Hash].Tag == 0)
{ {
/* Claim the slot in both, local and global tracking tables */ /* Claim the slot in both, local and global tracking tables */
AllocationsTrackingTable[Hash].Tag = Tag; AllocationsTrackingTable[Hash].Tag = Tag;
TableEntry->Tag = Tag; TableEntry->Tag = Tag;
}
} }
/* Restart the loop */ /* Restart the loop */
@@ -1923,13 +1964,7 @@ MM::Allocator::UnregisterAllocationTag(IN ULONG Tag,
IN MMPOOL_TYPE PoolType) IN MMPOOL_TYPE PoolType)
{ {
ULONG Hash, Index; ULONG Hash, Index;
PPOOL_TRACKING_TABLE CpuTable;
PPOOL_TRACKING_TABLE TableEntry; 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 */ /* Strip the protected pool bit */
Tag &= ~MM_POOL_PROTECTED; 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 */ /* Probe the tracking table until a match or an empty slot is found */
do do
{ {
/* Fetch the tracker entry from the CPU table */ /* Fetch the tracker entry from the table */
TableEntry = &CpuTable[Hash]; TableEntry = &AllocationsTrackingTable[Hash];
/* Check if the current entry tracks the requested pool tag */ /* Check if the current entry tracks the requested pool tag */
if(TableEntry->Tag == Tag) if(TableEntry->Tag == Tag)
@@ -1952,33 +1987,19 @@ MM::Allocator::UnregisterAllocationTag(IN ULONG Tag,
{ {
/* Update the non-paged allocation statistics */ /* Update the non-paged allocation statistics */
RTL::Atomic::Increment32(&TableEntry->NonPagedFrees); 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 else
{ {
/* Update the paged allocation statistics */ /* Update the paged allocation statistics */
RTL::Atomic::Increment32(&TableEntry->PagedFrees); 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 */ /* The allocation has been successfully tracked, return */
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 */ /* Advance to the next index as hash collision occurred */
Hash = (Hash + 1) & AllocationsTrackingTableMask; Hash = (Hash + 1) & AllocationsTrackingTableMask;
} }
@@ -2010,9 +2031,7 @@ MM::Allocator::UnregisterAllocationTagExpansion(IN ULONG Tag,
IN SIZE_T Bytes, IN SIZE_T Bytes,
IN MMPOOL_TYPE PoolType) IN MMPOOL_TYPE PoolType)
{ {
PPOOL_TRACKING_TABLE CpuTable;
ULONG Hash; ULONG Hash;
ULONG Processor;
/* Start a guarded code block */ /* Start a guarded code block */
{ {
@@ -2055,22 +2074,18 @@ MM::Allocator::UnregisterAllocationTagExpansion(IN ULONG Tag,
/* Target the index of the overflow bucket */ /* Target the index of the overflow bucket */
Hash = (ULONG)AllocationsTrackingTableSize - 1; 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 */ /* Update the appropriate statistics based on the pool type */
if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool) if((PoolType & MM_POOL_TYPE_MASK) == NonPagedPool)
{ {
/* Update the non-paged allocation statistics */ /* Update the non-paged allocation statistics */
RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].NonPagedFrees); RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].NonPagedFrees);
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].NonPagedBytes, 0 - Bytes); RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].NonPagedBytes, -(LONG_PTR)Bytes);
} }
else else
{ {
/* Update the paged allocation statistics */ /* Update the paged allocation statistics */
RTL::Atomic::Increment32((PLONG)&CpuTable[Hash].PagedFrees); RTL::Atomic::Increment32((PLONG)&AllocationsTrackingTable[Hash].PagedFrees);
RTL::Atomic::ExchangeAdd64((PLONG_PTR)&CpuTable[Hash].PagedBytes, 0 - Bytes); RTL::Atomic::ExchangeAdd64((PLONG_PTR)&AllocationsTrackingTable[Hash].PagedBytes, -(LONG_PTR)Bytes);
} }
} }

View File

@@ -18,7 +18,7 @@
* @param Count * @param Count
* The number of PTE entries to advance by. * 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 * @since XT 1.0
*/ */
@@ -96,7 +96,7 @@ MM::PageMap::GetNextEntry(IN PMMPTE Pte)
* @param Pte * @param Pte
* The PTE pointer to advance. * The PTE pointer to advance.
* *
* @return The advanced PTE pointer. * @return This routine returns the advanced PTE pointer.
* *
* @since XT 1.0 * @since XT 1.0
*/ */

View File

@@ -22,7 +22,7 @@ BOOLEAN
MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
{ {
/* Check if LA57 is enabled */ /* 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 * @param Attributes
* Specifies the attributes (protections, caching) to apply to the PTE. * 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 * @since XT 1.0
*/ */

View File

@@ -16,6 +16,8 @@
* Specifies the virtual address to verify. * Specifies the virtual address to verify.
* *
* @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used. * @return This routine returns ACCESS_VIOLATION regardless PML4 or PML5 is used.
*
* @since XT 1.0
*/ */
XTFASTCALL XTFASTCALL
XTSTATUS XTSTATUS

View File

@@ -99,7 +99,7 @@ MM::Pte::InitializePageTable(VOID)
MemoryLayout = MM::Manager::GetMemoryLayout(); MemoryLayout = MM::Manager::GetMemoryLayout();
/* Enable the Global Paging (PGE) feature */ /* 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 */ /* Check XPA status */
if(Xpa) if(Xpa)
@@ -123,7 +123,7 @@ MM::Pte::InitializePageTable(VOID)
} }
/* Flush the TLB to invalidate all non-global entries */ /* Flush the TLB to invalidate all non-global entries */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
/* Create a template PTE for mapping kernel pages */ /* Create a template PTE for mapping kernel pages */
MM::Paging::ClearPte(&TemplatePte); MM::Paging::ClearPte(&TemplatePte);

View File

@@ -42,9 +42,6 @@ KSPIN_LOCK MM::Allocator::BigAllocationsTrackingTableLock;
/* Maximum capacity of the tracking hash table */ /* Maximum capacity of the tracking hash table */
SIZE_T MM::Allocator::BigAllocationsTrackingTableSize; 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 */ /* Array of free page lists segregated by cache color */
PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1]; PMMCOLOR_TABLES MM::Colors::FreePages[FreePageList + 1];

View File

@@ -25,7 +25,7 @@
* @param Buffer * @param Buffer
* Supplies a buffer that receives the physical address. * 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 * @since XT 1.0
*/ */
@@ -153,7 +153,7 @@ MM::HardwarePool::AllocateHardwareMemory(IN PFN_NUMBER PageCount,
* @param MemoryAddress * @param MemoryAddress
* Supplies a pointer to a variable that receives the identity-mapped virtual address of the allocated memory. * 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 * @since XT 1.0
*/ */
@@ -207,7 +207,7 @@ MM::HardwarePool::AllocateRealModeMemory(IN PFN_NUMBER PageCount,
* @param VirtualAddress * @param VirtualAddress
* Supplies a buffer that receives the virtual address of the mapped pages. * 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 * @since XT 1.0
*/ */
@@ -374,7 +374,7 @@ MM::HardwarePool::RemapHardwareMemory(IN PVOID VirtualAddress,
* @param FlushTlb * @param FlushTlb
* Specifies whether to flush the TLB or not. * 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 * @since XT 1.0
*/ */

View File

@@ -251,7 +251,7 @@ MM::PageMapBasic::GetNextEntry(IN PMMPTE Pte)
* @param Pte * @param Pte
* The PTE pointer to advance. * The PTE pointer to advance.
* *
* @return The advanced PTE pointer. * @return This routine returns the advanced PTE pointer.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -472,7 +472,7 @@ MM::PageMapBasic::InitializePageMapInfo(VOID)
* @param PtePointer * @param PtePointer
* Pointer to the page table entry (PTE) to check. * 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 * @since XT 1.0
*/ */
@@ -666,7 +666,7 @@ MM::PageMapBasic::WritePte(IN PMMPTE Pte,
* @param Count * @param Count
* The number of PTE entries to advance by. * 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 * @since XT 1.0
*/ */
@@ -721,7 +721,7 @@ MM::PageMapXpa::GetNextEntry(IN PMMPTE Pte)
* @param Pte * @param Pte
* The PTE pointer to advance. * The PTE pointer to advance.
* *
* @return The advanced PTE pointer. * @return This routine returns the advanced PTE pointer.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -942,7 +942,7 @@ MM::PageMapXpa::InitializePageMapInfo(VOID)
* @param PtePointer * @param PtePointer
* Pointer to the page table entry (PTE) to check. * 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 * @since XT 1.0
*/ */

View File

@@ -22,7 +22,7 @@ BOOLEAN
MM::Paging::GetExtendedPhysicalAddressingStatus(VOID) MM::Paging::GetExtendedPhysicalAddressingStatus(VOID)
{ {
/* Check if PAE is enabled */ /* 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 * @param Attributes
* Specifies the attributes (protections, caching) to apply to the PTE. * 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 * @since XT 1.0
*/ */

View File

@@ -150,7 +150,7 @@ MM::Pfn::InitializePageTablePfns(VOID)
RootLevel = 3; RootLevel = 3;
/* Retrieve the PFN of the PML3 table and its virtual base address */ /* 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); RootPte = (PMMPTE)MM::Paging::GetPpeAddress(NULLPTR);
} }
else else
@@ -159,7 +159,7 @@ MM::Pfn::InitializePageTablePfns(VOID)
RootLevel = 2; RootLevel = 2;
/* Retrieve the PFN of the PML2 table and its virtual base address */ /* 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); RootPte = (PMMPTE)MM::Paging::GetPdeAddress(NULLPTR);
} }

View File

@@ -70,13 +70,13 @@ MM::Pte::InitializePageTable(VOID)
/* Get CPU features */ /* Get CPU features */
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Check if Paging Global Extensions (PGE) is supported */ /* Check if Paging Global Extensions (PGE) is supported */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)
{ {
/* Enable the Global Paging (PGE) feature */ /* 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 */ /* 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 */ /* Flush the TLB to invalidate all non-global entries */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
/* Create a template PTE for mapping kernel pages */ /* Create a template PTE for mapping kernel pages */
MM::Paging::ClearPte(&TemplatePte); MM::Paging::ClearPte(&TemplatePte);

View File

@@ -19,7 +19,7 @@
* @param StackSize * @param StackSize
* Supplies the size of the stack to be allocated, in bytes. * 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 * @since XT 1.0
*/ */
@@ -95,7 +95,7 @@ MM::KernelPool::AllocateKernelStack(OUT PVOID *Stack,
* @param StructuresData * @param StructuresData
* Supplies a pointer to the memory area that will contain the allocated buffer. * 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 * @since XT 1.0
*/ */

View File

@@ -279,13 +279,13 @@ MM::Manager::InitializeMemoryManager(VOID)
MM::Pool::InitializePagedPool(); MM::Pool::InitializePagedPool();
/* Flush TLB */ /* Flush TLB */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
} }
/** /**
* Allocates and maps the Kernel Shared Data page to its hardcoded virtual address. * 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 * @since XT 1.0
*/ */

View File

@@ -18,7 +18,7 @@
* @param Count * @param Count
* The number of PTE entries to advance by. * 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 * @since XT 1.0
*/ */
@@ -98,39 +98,39 @@ MM::Paging::FlushTlb(VOID)
ULONG_PTR Cr4; ULONG_PTR Cr4;
/* Save interrupts state and disable them */ /* Save interrupts state and disable them */
Interrupts = AR::CpuFunc::InterruptsEnabled(); Interrupts = AR::CpuFunctions::InterruptsEnabled();
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
/* Get CPU features */ /* Get CPU features */
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES; CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
AR::CpuFunc::CpuId(&CpuRegisters); AR::CpuFunctions::CpuId(&CpuRegisters);
/* Check if Paging Global Extensions (PGE) is supported */ /* Check if Paging Global Extensions (PGE) is supported */
if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE) if(CpuRegisters.Edx & CPUID_FEATURES_EDX_PGE)
{ {
/* Read CR4 */ /* Read CR4 */
Cr4 = AR::CpuFunc::ReadControlRegister(4); Cr4 = AR::CpuFunctions::ReadControlRegister(4);
/* Disable PGE */ /* Disable PGE */
AR::CpuFunc::WriteControlRegister(4, Cr4 & ~CR4_PGE); AR::CpuFunctions::WriteControlRegister(4, Cr4 & ~CR4_PGE);
/* Flush the TLB */ /* Flush the TLB */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
/* Restore CR4 */ /* Restore CR4 */
AR::CpuFunc::WriteControlRegister(4, Cr4); AR::CpuFunctions::WriteControlRegister(4, Cr4);
} }
else else
{ {
/* Simply flush the TLB */ /* Simply flush the TLB */
AR::CpuFunc::FlushTlb(); AR::CpuFunctions::FlushTlb();
} }
/* Check if interrupts should be enabled */ /* Check if interrupts should be enabled */
if(Interrupts) if(Interrupts)
{ {
/* Re-enable interrupts */ /* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag(); AR::CpuFunctions::SetInterruptFlag();
} }
} }
@@ -158,7 +158,7 @@ MM::Paging::GetNextEntry(IN PMMPTE Pte)
* @param Pte * @param Pte
* The PTE pointer to advance. * The PTE pointer to advance.
* *
* @return The advanced PTE pointer. * @return This routine returns the advanced PTE pointer.
* *
* @since XT 1.0 * @since XT 1.0
*/ */
@@ -517,7 +517,7 @@ MM::Paging::InitializePageMapSupport(VOID)
* @param PtePointer * @param PtePointer
* Pointer to the page table entry (PTE) to check. * 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 * @since XT 1.0
*/ */

View File

@@ -390,7 +390,7 @@ MM::Pfn::GetHighestPhysicalPage(VOID)
/** /**
* Retrieves the total number of physical pages managed by the system. * 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 * @since XT 1.0
*/ */

View File

@@ -539,7 +539,7 @@ MM::Pte::ReserveSystemPtes(IN PFN_COUNT NumberOfPtes,
TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes; TotalSystemFreePtes[SystemPtePoolType] -= NumberOfPtes;
/* Flush the TLB to ensure address translation consistency */ /* 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 a pointer to the start of the reserved PTE block */
return ReservedPte; return ReservedPte;

View File

@@ -63,7 +63,7 @@ PO::Idle::Idle0Function(IN PPROCESSOR_POWER_STATE PowerState)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID
@@ -89,7 +89,7 @@ PO::Idle::PerfIdle(PPROCESSOR_POWER_STATE PowerState)
* *
* @return This routine does not return any value. * @return This routine does not return any value.
* *
* @since NT 5.1 * @since XT 1.0
*/ */
XTAPI XTAPI
VOID VOID

View File

@@ -73,7 +73,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0);
/* Continue search */ /* Continue search */
@@ -128,6 +128,6 @@ _purecall(VOID)
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0);
} }

View File

@@ -73,7 +73,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0);
/* Continue search */ /* Continue search */
@@ -128,6 +128,6 @@ _purecall(VOID)
UNIMPLEMENTED; UNIMPLEMENTED;
/* Disable interrupts and hang */ /* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag(); AR::CpuFunctions::ClearInterruptFlag();
KE::Crash::Panic(0); KE::Crash::Panic(0);
} }

723
xtoskrnl/rtl/rbtree.cc Normal file
View 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);
}