My Project
Loading...
Searching...
No Matches
mminit.c
Go to the documentation of this file.
1/*++
2
3Module Name:
4
5 mminit.c
6
7Purpose:
8
9 This translation unit contains the implementation of memory manager initialization routines.
10
11Author:
12
13 slep (Matanel) 2025.
14
15Revision History:
16
17--*/
18
19#include "../../includes/mm.h"
20#include "../../includes/me.h"
21#include "../../includes/mg.h"
22#include "../../assert.h"
23
24#define IA32_PAT 0x277
25
26static
27bool
28MiIsPATAvailable(void)
29
30{
31 uint32_t eax, ebx, ecx, edx;
32 __cpuid(1, eax, ebx, ecx, edx);
33 return (edx & (1 << 16)) != 0;
34}
35
36static
37void
38MiInitializePAT(void)
39
40{
41 uint64_t pat =
42 0x00 | // 0 = WB
43 (0x01ULL << 8) | // 1 = WT
44 (0x02ULL << 16) | // 2 = UC-
45 (0x03ULL << 24) | // 3 = UC
46 (0x00ULL << 32) | // 4 = WB
47 (0x01ULL << 40) | // 5 = WC
48 (0x02ULL << 48) | // 6 = UC-
49 (0x03ULL << 56); // 7 = UC
50
51 __writemsr(IA32_PAT, pat);
52}
53
54bool
56 IN uint8_t Phase,
57 IN PBOOT_INFO BootInformation
58)
59
60/*++
61
62 Routine description:
63
64 Initializes the memory manager of the system.
65
66 Arguments:
67
68 [IN] uint8_t Phase - Specifies the phase of the system for correct init routines. (enum SYSTEM_PHASE_ROUTINE)
69 [IN] PBOOT_INFO BootInformation - The boot information supplied by the UEFI Bootloader (can be NULL in later phases, look below)
70
71 Phase Demands:
72
73 1 - BootInformation
74 2 - None.
75
76 Phase Does:
77
78 1 (SYSTEM_PHASE_INITIALIZE_ALL) - Initializes PAT and the core memory managment routines. (PFN Database, Virtual Address bitmap, PAT, PTE Database, etc.)
79
80 2 (SYSTEM_PHASE_INITIALIZE_PAT_ONLY) - Initializes PAT only (used in AP startup)
81
82 Return Values:
83
84 True or false if the phase given has succeeded initilization.
85
86--*/
87
88{
89 // Currently we only support the first and only phase.
90 if (Phase == SYSTEM_PHASE_INITIALIZE_ALL) {
91
92 // Initialize PAT (Page Attribute Table)
93 bool PatAvailable = MiIsPATAvailable();
94 assert(PatAvailable == true);
95 if (PatAvailable) {
96 MiInitializePAT();
97 }
98
99 // Initialize all memory managment routines (PFN Database, VA Space, Pools, MMIO, PTE Database)
100 // If we fail init of one of them, we bugcheck, since they are mandatory for operation.
101 MTSTATUS st = MiInitializePfnDatabase(BootInformation);
102 if (MT_FAILURE(st)) {
105 (void*)(uintptr_t)st,
106 NULL,
107 NULL,
108 NULL
109 );
110 }
111
114 }
115
117 if (MT_FAILURE(st)) {
120 (void*)(uintptr_t)st,
121 NULL,
122 NULL,
123 NULL
124 );
125 }
126
127 // Phase 1 Done.
128 return true;
129 }
130
131 else if (Phase == SYSTEM_PHASE_INITIALIZE_PAT_ONLY) {
132 // Phase only initializes PAT for the current core.
133 // Initialize PAT (Page Attribute Table)
134 bool PatAvailable = MiIsPATAvailable();
135 assert(PatAvailable == true);
136 if (PatAvailable) {
137 MiInitializePAT();
138 }
139
140 // Return if PAT is available on the current core or not (if available, it's initialized)
141 return PatAvailable;
142 }
143
144 else {
145 // Only phase 1 & 2 are supported currently.
147 }
148}
149
150extern GOP_PARAMS gop_local;
152
153void
155 IN PBOOT_INFO BootInfo
156)
157
158
159/*++
160
161 Routine description:
162
163 Moves UEFI Memory that is mapped below the kernel half to the kernel half.
164
165 Arguments:
166
167 [IN] PBOOT_INFO BootInformation - The boot information supplied by the UEFI Bootloader.
168
169
170 Return Values:
171
172 None.
173
174 Notes:
175
176 Currently the only UEFI memory that is below the higher half is the GOP. (and RSDP, but that is processed during kernel startup, so its fine)
177
178--*/
179
180{
181 // Move GOP to higher half, luckily i developed this extremely advanced memory api (its just advancing pointers)
182 uintptr_t Virt = MiTranslateVirtualToPhysical((void*)gop_local.FrameBufferBase);
183
184#ifdef DEBUG
185 uint64_t oldBase = gop_local.FrameBufferBase;
186#endif
187
188 gop_local.FrameBufferBase = (uint64_t)MmMapIoSpace(Virt, gop_local.FrameBufferSize, MmCached);
189 assert(gop_local.FrameBufferBase != Virt);
190 assert((void*)gop_local.FrameBufferBase != NULL);
191
192 // Unmap the previous PTE.
194
195#ifdef DEBUG
196 assert(MmIsAddressValid((uintptr_t)oldBase) == false);
197#endif
198 uintptr_t BootInfoPhys = MiTranslateVirtualToPhysical((void*)BootInfo);
199
200 // Destroy the boot_info struct PTE.
201 // First, memory set it to 0 (just for good measure)
202 kmemset(BootInfo, 0, sizeof(BOOT_INFO));
203
204 // Great, unmap it now.
205 assert(sizeof(BOOT_INFO) <= VirtualPageSize); // If the size is larger, we would need to do a for loop.
206 MiUnmapPte(MiGetPtePointer((uintptr_t)BootInfo));
207 assert(MmIsAddressValid((uintptr_t)BootInfo) == false);
208
209 // Free its physical frame.
211}
BOOT_INFO boot_info_local
Definition kernel.c:27
#define IN
Definition annotations.h:7
#define assert(...)
Definition assert.h:57
NORETURN void MeBugCheck(IN enum _BUGCHECK_CODES BugCheckCode)
Definition bugcheck.c:214
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
Definition bugcheck.c:305
GOP_PARAMS gop_local
Definition gop.c:247
struct _BOOT_INFO * PBOOT_INFO
struct _GOP_PARAMS GOP_PARAMS
struct _BOOT_INFO BOOT_INFO
FORCEINLINE void __writemsr(uint32_t msr, uint64_t value)
Definition intrin.h:200
uintptr_t MiTranslateVirtualToPhysical(IN void *VirtualAddress)
Definition map.c:456
PMMPTE MiGetPtePointer(IN uintptr_t va)
Definition map.c:76
void MiUnmapPte(IN PMMPTE pte)
Definition map.c:385
@ PFN_DATABASE_INIT_FAILURE
Definition me.h:119
@ POOL_INIT_FAILURE
Definition me.h:121
@ INVALID_INITIALIZATION_PHASE
Definition me.h:124
@ VA_SPACE_INIT_FAILURE
Definition me.h:120
#define PHYSICAL_TO_PPFN(PHYS)
Definition mm.h:64
@ SYSTEM_PHASE_INITIALIZE_PAT_ONLY
Definition mm.h:376
@ SYSTEM_PHASE_INITIALIZE_ALL
Definition mm.h:375
@ MmCached
Definition mm.h:344
#define PPFN_TO_INDEX(PPFN)
Definition mm.h:116
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
Definition mm.h:540
#define MmIsAddressValid(VirtualAddress)
Definition mm.h:234
#define VirtualPageSize
Definition mm.h:53
#define IA32_PAT
Definition mminit.c:24
void MiMoveUefiDataToHigherHalf(IN PBOOT_INFO BootInfo)
Definition mminit.c:154
bool MmInitSystem(IN uint8_t Phase, IN PBOOT_INFO BootInformation)
Definition mminit.c:55
void * MmMapIoSpace(IN uintptr_t PhysicalAddress, IN size_t NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition mmio.c:269
#define MT_FAILURE(Status)
Definition mtstatus.h:16
int32_t MTSTATUS
Definition mtstatus.h:12
void MiReleasePhysicalPage(IN PAGE_INDEX PfnIndex)
Definition pfn.c:421
MTSTATUS MiInitializePfnDatabase(IN PBOOT_INFO BootInfo)
Definition pfn.c:100
MTSTATUS MiInitializePoolSystem(void)
Definition pool.c:36
bool MiInitializePoolVaSpace(void)
Definition va.c:35