26#define CR0_MP (1UL << 1)
27#define CR0_EM (1UL << 2)
28#define CR0_WP (1UL << 16)
29#define CR0_CD (1UL << 30)
31#define CR4_OSFXSR (1UL << 9)
32#define CR4_OSXMMEXCPT (1UL << 10)
33#define CR4_UMIP (1UL << 11)
34#define CR4_FSGSBASE (1UL << 16)
35#define CR4_SMEP (1UL << 20)
36#define CR4_SMAP (1UL << 21)
39#define CPUID_1_EDX_SSE (1UL << 25)
40#define CPUID_1_EDX_SSE2 (1UL << 26)
41#define CPUID_7_EBX_SMEP (1UL << 7)
42#define CPUID_7_EBX_SMAP (1UL << 20)
45static void InitialiseControlRegisters(
void) {
48 unsigned int eax, ebx, ecx, edx;
63 __asm__
volatile(
"cpuid" :
"=a"(eax),
"=b"(ebx),
"=c"(ecx),
"=d"(edx) :
"a"(1),
"c"(0));
79 __asm__
volatile(
"cpuid" :
"=a"(eax),
"=b"(ebx),
"=c"(ecx),
"=d"(edx) :
"a"(7),
"c"(0));
98 unsigned int mxcsr = 0x1f80;
102 : :
"m"(mxcsr) :
"memory"
112static void MeInitGdtTssForCurrentProcessor(
void) {
115 uint64_t* gdt = cur->
gdt;
118 gdt[1] = 0x00AF9A000000FFFF;
119 gdt[2] = 0x00CF92000000FFFF;
120 gdt[3] = 0x00CFF2000000FFFF;
121 gdt[4] = 0x00AFFA000000FFFF;
122 uint64_t tss_base = (uint64_t)tss;
123 uint32_t limit =
sizeof(
TSS) - 1;
128 tss->io_map_base =
sizeof(
TSS);
129 tss->rsp0 = (uint64_t)cur->
Rsp0;
131 tss->ist[1] = (uint64_t)cur->IstDFStackTop;
132 tss->ist[2] = (uint64_t)cur->IstTimerStackTop;
133 tss->ist[3] = (uint64_t)cur->IstIpiStackTop;
135 uint64_t tss_limit = (uint64_t)limit;
137 uint64_t low = (tss_limit & 0xFFFFULL)
138 | ((tss_base & 0xFFFFFFULL) << 16)
140 | (((tss_limit >> 16) & 0xFULL) << 48)
141 | (((tss_base >> 24) & 0xFFULL) << 56);
144 uint64_t high = (tss_base >> 32) & 0xFFFFFFFFULL;
149 const int GDT_ENTRIES = 7;
151 GDTPtr gdtr = { .limit = (GDT_ENTRIES *
sizeof(uint64_t)) - 1, .base = (uint64_t)gdt };
152 __asm__
volatile(
"lgdt %0" : :
"m"(gdtr));
155 "leaq 1f(%%rip), %%rax\n\t"
159 : : :
"rax",
"memory"
164 unsigned short sel = 0x28;
165 __asm__
volatile(
"ltr %w0" ::
"r"(sel));
174 IN bool InitializeStandardRoutine,
201 if (InitializeStandardRoutine && !AreYouAP)
goto StartInit;
203 InitialiseControlRegisters();
207 CPU->schedulerEnabled = NULL;
208 CPU->currentThread = NULL;
209 CPU->readyQueue.head = CPU->readyQueue.tail = NULL;
211 CPU->DpcData.DpcLock.locked = 0;
215 CPU->MaximumDpcQueueDepth = 4;
216 CPU->MinimumDpcRate = 1000;
217 CPU->DpcRequestRate = 0;
218 CPU->DpcRoutineActive =
false;
219 CPU->DpcInterruptRequested =
false;
224 if (!InitializeStandardRoutine && !AreYouAP)
return;
240 bool exists = (IstTimer && IstIpi && IstDf && IstPf && Rsp0) != 0;
244 CPU->IstPFStackTop = IstPf;
245 CPU->IstDFStackTop = IstDf;
246 CPU->IstIpiStackTop = IstIpi;
247 CPU->IstTimerStackTop = IstTimer;
258 MeInitGdtTssForCurrentProcessor();
void gop_printf(uint32_t color, const char *fmt,...)
FORCEINLINE uint64_t __readmsr(uint32_t msr)
FORCEINLINE void __writemsr(uint32_t msr, uint64_t value)
FORCEINLINE unsigned long int __read_cr0(void)
FORCEINLINE void __write_cr0(unsigned long int val)
FORCEINLINE void __write_cr4(unsigned long val)
FORCEINLINE void __write_dr(int reg, uint64_t val)
FORCEINLINE unsigned long __read_cr4(void)
FORCEINLINE void __lidt(void *idt_ptr)
FORCEINLINE PPROCESSOR MeGetCurrentProcessor(void)
void MeInitializeProcessor(IN PPROCESSOR CPU, IN bool InitializeStandardRoutine, IN bool AreYouAP)
#define COLOR_RED
Colors definitions for easier access.
struct _IDT_ENTRY_64 IDT_ENTRY64
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
void * MiCreateKernelStack(IN bool LargeStack)
FORCEINLINE void InitializeListHead(PDOUBLY_LINKED_LIST Head)
void * MmAllocatePoolWithTag(IN enum _POOL_TYPE PoolType, IN size_t NumberOfBytes, IN uint32_t Tag)
void MtSetupSyscall(void)