25#define CR0_MP (1UL << 1)
26#define CR0_EM (1UL << 2)
27#define CR0_WP (1UL << 16)
28#define CR0_CD (1UL << 30)
30#define CR4_OSFXSR (1UL << 9)
31#define CR4_OSXMMEXCPT (1UL << 10)
32#define CR4_UMIP (1UL << 11)
33#define CR4_FSGSBASE (1UL << 16)
34#define CR4_SMEP (1UL << 20)
35#define CR4_SMAP (1UL << 21)
38#define CPUID_1_EDX_SSE (1UL << 25)
39#define CPUID_1_EDX_SSE2 (1UL << 26)
40#define CPUID_7_EBX_SMEP (1UL << 7)
41#define CPUID_7_EBX_SMAP (1UL << 20)
44static void InitialiseControlRegisters(
void) {
47 unsigned int eax, ebx, ecx, edx;
62 __asm__
volatile(
"cpuid" :
"=a"(eax),
"=b"(ebx),
"=c"(ecx),
"=d"(edx) :
"a"(1),
"c"(0));
78 __asm__
volatile(
"cpuid" :
"=a"(eax),
"=b"(ebx),
"=c"(ecx),
"=d"(edx) :
"a"(7),
"c"(0));
94 unsigned int mxcsr = 0x1f80;
98 : :
"m"(mxcsr) :
"memory"
103static void MeInitGdtTssForCurrentProcessor(
void) {
106 uint64_t* gdt = cur->
gdt;
109 gdt[1] = 0x00AF9A000000FFFF;
110 gdt[2] = 0x00CF92000000FFFF;
112 gdt[3] = 0x00AFFA000000FFFF;
113 gdt[4] = 0x00CFF2000000FFFF;
114 uint64_t tss_base = (uint64_t)tss;
115 uint32_t limit =
sizeof(
TSS) - 1;
120 tss->io_map_base =
sizeof(
TSS);
121 tss->rsp0 = (uint64_t)cur->
Rsp0;
123 tss->ist[1] = (uint64_t)cur->IstDFStackTop;
124 tss->ist[2] = (uint64_t)cur->IstTimerStackTop;
125 tss->ist[3] = (uint64_t)cur->IstIpiStackTop;
127 uint64_t tss_limit = (uint64_t)limit;
129 uint64_t low = (tss_limit & 0xFFFFULL)
130 | ((tss_base & 0xFFFFFFULL) << 16)
132 | (((tss_limit >> 16) & 0xFULL) << 48)
133 | (((tss_base >> 24) & 0xFFULL) << 56);
136 uint64_t high = (tss_base >> 32) & 0xFFFFFFFFULL;
141 const int GDT_ENTRIES = 7;
143 GDTPtr gdtr = { .limit = (GDT_ENTRIES *
sizeof(uint64_t)) - 1, .base = (uint64_t)gdt };
144 __asm__
volatile(
"lgdt %0" : :
"m"(gdtr));
147 "leaq 1f(%%rip), %%rax\n\t"
151 : : :
"rax",
"memory"
156 unsigned short sel = 0x28;
157 __asm__
volatile(
"ltr %w0" ::
"r"(sel));
166 IN bool InitializeStandardRoutine,
193 if (InitializeStandardRoutine && !AreYouAP)
goto StartInit;
195 InitialiseControlRegisters();
199 CPU->schedulerEnabled = NULL;
200 CPU->currentThread = NULL;
201 CPU->readyQueue.head = CPU->readyQueue.tail = NULL;
203 CPU->DpcData.DpcLock.locked = 0;
207 CPU->MaximumDpcQueueDepth = 4;
208 CPU->MinimumDpcRate = 1000;
209 CPU->DpcRequestRate = 0;
210 CPU->DpcRoutineActive =
false;
211 CPU->DpcInterruptRequested =
false;
212 if (!InitializeStandardRoutine && !AreYouAP)
return;
227 bool exists = (IstTimer && IstIpi && IstDf && IstPf && Rsp0) != 0;
230 CPU->IstPFStackTop = IstPf;
231 CPU->IstDFStackTop = IstDf;
232 CPU->IstIpiStackTop = IstIpi;
233 CPU->IstTimerStackTop = IstTimer;
244 MeInitGdtTssForCurrentProcessor();
void gop_printf(uint32_t color, const char *fmt,...)
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
#define LAPIC_TIMER_VECTOR
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)