ReactOS 0.4.17-dev-1190-g4c812f4
patpge.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for patpge.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define PDE_BITS   10
 
#define PTE_BITS   10
 

Functions

ULONG_PTR NTAPI Ki386EnableGlobalPage (IN ULONG_PTR Context)
 
static ULONG_PTR NTAPI Ki386InitializePATTarget (IN ULONG_PTR Context)
 
VOID NTAPI KiInitializePAT (VOID)
 
ULONG_PTR NTAPI Ki386EnableTargetLargePage (IN ULONG_PTR Context)
 
PVOID NTAPI Ki386AllocateContiguousMemory (PLARGE_IDENTITY_MAP IdentityMap, ULONG PagesCount, BOOLEAN InLower4Gb)
 
PHYSICAL_ADDRESS NTAPI Ki386BuildIdentityBuffer (PLARGE_IDENTITY_MAP IdentityMap, PVOID StartPtr, ULONG Length)
 
BOOLEAN NTAPI Ki386IdentityMapMakeValid (PLARGE_IDENTITY_MAP IdentityMap, PHARDWARE_PTE Pde, PHARDWARE_PTE *PageTable)
 
BOOLEAN NTAPI Ki386MapAddress (PLARGE_IDENTITY_MAP IdentityMap, ULONG_PTR VirtualPtr, PHYSICAL_ADDRESS PhysicalPtr)
 
VOID NTAPI Ki386ConvertPte (PHARDWARE_PTE Pte)
 
BOOLEAN NTAPI Ki386CreateIdentityMap (PLARGE_IDENTITY_MAP IdentityMap, PVOID StartPtr, ULONG PagesCount)
 
VOID NTAPI Ki386FreeIdentityMap (PLARGE_IDENTITY_MAP IdentityMap)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file patpge.c.

◆ PDE_BITS

#define PDE_BITS   10

Definition at line 15 of file patpge.c.

◆ PTE_BITS

#define PTE_BITS   10

Definition at line 16 of file patpge.c.

Function Documentation

◆ Ki386AllocateContiguousMemory()

PVOID NTAPI Ki386AllocateContiguousMemory ( PLARGE_IDENTITY_MAP  IdentityMap,
ULONG  PagesCount,
BOOLEAN  InLower4Gb 
)

Definition at line 108 of file patpge.c.

111{
112 PHYSICAL_ADDRESS AddressMask;
114 ULONG SizeInBytes = PagesCount * PAGE_SIZE;
115
116 /* Initialize acceptable address mask to any possible address */
117 AddressMask.LowPart = 0xFFFFFFFF;
118 AddressMask.HighPart = 0xFFFFFFFF;
119
120 /* Mark out higher 4Gb if caller asked so */
121 if (InLower4Gb) AddressMask.HighPart = 0;
122
123 /* Try to allocate the memory */
124 Result = MmAllocateContiguousMemory(SizeInBytes, AddressMask);
125 if (!Result) return NULL;
126
127 /* Zero it out */
128 RtlZeroMemory(Result, SizeInBytes);
129
130 /* Track allocated pages in the IdentityMap structure */
131 IdentityMap->PagesList[IdentityMap->PagesCount] = Result;
132 IdentityMap->PagesCount++;
133
134 return Result;
135}
PVOID NTAPI MmAllocateContiguousMemory(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: contmem.c:626
#define NULL
Definition: types.h:112
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PVOID PagesList[30]
Definition: ke.h:294
ULONG PagesCount
Definition: ke.h:293
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
ULONG LowPart
Definition: typedefs.h:106
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by Ki386IdentityMapMakeValid(), and Ki386MapAddress().

◆ Ki386BuildIdentityBuffer()

PHYSICAL_ADDRESS NTAPI Ki386BuildIdentityBuffer ( PLARGE_IDENTITY_MAP  IdentityMap,
PVOID  StartPtr,
ULONG  Length 
)

Definition at line 139 of file patpge.c.

142{
143 // TODO: Check whether all pages are below 4GB boundary
144 return MmGetPhysicalAddress(StartPtr);
145}
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:663

Referenced by Ki386CreateIdentityMap().

◆ Ki386ConvertPte()

VOID NTAPI Ki386ConvertPte ( PHARDWARE_PTE  Pte)

Definition at line 209 of file patpge.c.

210{
211 PVOID VirtualPtr;
212 PHYSICAL_ADDRESS PhysicalPtr;
213
214 /* Get virtual and physical addresses */
215 VirtualPtr = (PVOID)(Pte->PageFrameNumber << PAGE_SHIFT);
216 PhysicalPtr = MmGetPhysicalAddress(VirtualPtr);
217
218 /* Map its physical address in the page table provided by the caller */
219 Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT);
220}
ULONG_PTR PFN_NUMBER
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ULONG64 PageFrameNumber
Definition: mmtypes.h:78
void * PVOID
Definition: typedefs.h:50
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by Ki386CreateIdentityMap().

◆ Ki386CreateIdentityMap()

BOOLEAN NTAPI Ki386CreateIdentityMap ( PLARGE_IDENTITY_MAP  IdentityMap,
PVOID  StartPtr,
ULONG  PagesCount 
)

Definition at line 224 of file patpge.c.

225{
227 ULONG PteIndex;
228 PHYSICAL_ADDRESS IdentityPtr;
229
230 /* Zero out the IdentityMap contents */
231 RtlZeroMemory(IdentityMap, sizeof(LARGE_IDENTITY_MAP));
232
233 /* Get the pointer to the physical address and save it in the struct */
234 IdentityPtr = Ki386BuildIdentityBuffer(IdentityMap, StartPtr, PagesCount);
235 IdentityMap->StartAddress = IdentityPtr.LowPart;
236 if (IdentityMap->StartAddress == 0)
237 {
238 DPRINT1("Failed to get buffer for large pages identity mapping\n");
239 return FALSE;
240 }
241 DPRINT("IdentityMap->StartAddress %p\n", IdentityMap->StartAddress);
242
243 /* Map all pages */
244 for (Ptr = (ULONG_PTR)StartPtr;
245 Ptr < (ULONG_PTR)StartPtr + PagesCount * PAGE_SIZE;
246 Ptr += PAGE_SIZE, IdentityPtr.QuadPart += PAGE_SIZE)
247 {
248 /* Map virtual address */
249 if (!Ki386MapAddress(IdentityMap, Ptr, IdentityPtr)) return FALSE;
250
251 /* Map physical address */
252 if (!Ki386MapAddress(IdentityMap, IdentityPtr.LowPart, IdentityPtr)) return FALSE;
253 }
254
255 /* Convert all PTEs in the page directory from virtual to physical,
256 because Ki386IdentityMapMakeValid mapped only virtual addresses */
257 for (PteIndex = 0; PteIndex < (PAGE_SIZE / sizeof(HARDWARE_PTE)); PteIndex++)
258 {
259 if (IdentityMap->TopLevelDirectory[PteIndex].Valid != 0)
260 Ki386ConvertPte(&IdentityMap->TopLevelDirectory[PteIndex]);
261 }
262
263 /* Save the page directory address (allocated by Ki386MapAddress) */
264 IdentityMap->Cr3 = MmGetPhysicalAddress(IdentityMap->TopLevelDirectory).LowPart;
265
266 DPRINT("IdentityMap->Cr3 0x%x\n", IdentityMap->Cr3);
267
268 return TRUE;
269}
#define DPRINT1
Definition: precomp.h:8
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define HARDWARE_PTE
Definition: mmtypes.h:186
PHYSICAL_ADDRESS NTAPI Ki386BuildIdentityBuffer(PLARGE_IDENTITY_MAP IdentityMap, PVOID StartPtr, ULONG Length)
Definition: patpge.c:139
BOOLEAN NTAPI Ki386MapAddress(PLARGE_IDENTITY_MAP IdentityMap, ULONG_PTR VirtualPtr, PHYSICAL_ADDRESS PhysicalPtr)
Definition: patpge.c:180
VOID NTAPI Ki386ConvertPte(PHARDWARE_PTE Pte)
Definition: patpge.c:209
#define DPRINT
Definition: sndvol32.h:73
ULONG64 Valid
Definition: mmtypes.h:66
ULONG_PTR StartAddress
Definition: ke.h:292
PHARDWARE_PTE TopLevelDirectory
Definition: ke.h:290
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ Ki386EnableGlobalPage()

ULONG_PTR NTAPI Ki386EnableGlobalPage ( IN ULONG_PTR  Context)

Definition at line 23 of file patpge.c.

24{
25 //PLONG Count;
26#if defined(_GLOBAL_PAGES_ARE_AWESOME_)
27 ULONG Cr4;
28#endif
30
31 /* Disable interrupts */
33
34 /* Spin until other processors are ready */
35 //Count = (PLONG)Context;
36 //InterlockedDecrement(Count);
37 //while (*Count) YieldProcessor();
38
39#if defined(_GLOBAL_PAGES_ARE_AWESOME_)
40
41 /* Get CR4 and ensure global pages are disabled */
42 Cr4 = __readcr4();
43 ASSERT(!(Cr4 & CR4_PGE));
44
45 /* Reset CR3 to flush the TLB */
47
48 /* Now enable PGE */
49 __writecr4(Cr4 | CR4_PGE);
50
51#endif
52
53 /* Restore interrupts and return */
55 return 0;
56}
unsigned char BOOLEAN
Definition: actypes.h:127
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1850
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1857
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1826
__INTRIN_INLINE void __writecr4(unsigned int Data)
Definition: intrin_x86.h:1831
#define ASSERT(a)
Definition: mode.c:44
#define CR4_PGE
Definition: ketypes.h:161
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
FORCEINLINE BOOLEAN KeDisableInterrupts(VOID)
Definition: ke.h:249
FORCEINLINE VOID KeRestoreInterrupts(BOOLEAN WereEnabled)
Definition: ke.h:264

Referenced by KiInitMachineDependent().

◆ Ki386EnableTargetLargePage()

ULONG_PTR NTAPI Ki386EnableTargetLargePage ( IN ULONG_PTR  Context)

Definition at line 96 of file patpge.c.

97{
99
100 /* Call helper function with the start address and temporary page table pointer */
101 Ki386EnableCurrentLargePage(IdentityMap->StartAddress, IdentityMap->Cr3);
102
103 return 0;
104}
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
struct _LARGE_IDENTITY_MAP * PLARGE_IDENTITY_MAP
VOID NTAPI Ki386EnableCurrentLargePage(IN ULONG_PTR StartAddress, IN ULONG Cr3)

Referenced by KiInitMachineDependent().

◆ Ki386FreeIdentityMap()

VOID NTAPI Ki386FreeIdentityMap ( PLARGE_IDENTITY_MAP  IdentityMap)

Definition at line 273 of file patpge.c.

274{
275 ULONG Page;
276
277 DPRINT("Freeing %lu pages allocated for identity mapping\n", IdentityMap->PagesCount);
278
279 /* Free all allocated pages, if any */
280 for (Page = 0; Page < IdentityMap->PagesCount; Page++)
282}
VOID NTAPI MmFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:653
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1287

◆ Ki386IdentityMapMakeValid()

BOOLEAN NTAPI Ki386IdentityMapMakeValid ( PLARGE_IDENTITY_MAP  IdentityMap,
PHARDWARE_PTE  Pde,
PHARDWARE_PTE *  PageTable 
)

Definition at line 149 of file patpge.c.

152{
153 ULONG NewPage;
154
155 if (Pde->Valid == 0)
156 {
157 /* Invalid, so allocate a new page for it */
158 NewPage = (ULONG)Ki386AllocateContiguousMemory(IdentityMap, 1, FALSE);
159 if (!NewPage) return FALSE;
160
161 /* Set PFN to its virtual address and mark it as valid */
162 Pde->PageFrameNumber = NewPage >> PAGE_SHIFT;
163 Pde->Valid = 1;
164
165 /* Pass page table address to the caller */
166 if (PageTable) *PageTable = (PHARDWARE_PTE)NewPage;
167 }
168 else
169 {
170 /* Valid entry, just pass the page table address to the caller */
171 if (PageTable)
173 }
174
175 return TRUE;
176}
#define PHARDWARE_PTE
Definition: mmtypes.h:187
PVOID NTAPI Ki386AllocateContiguousMemory(PLARGE_IDENTITY_MAP IdentityMap, ULONG PagesCount, BOOLEAN InLower4Gb)
Definition: patpge.c:108
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43

Referenced by Ki386MapAddress().

◆ Ki386InitializePATTarget()

static ULONG_PTR NTAPI Ki386InitializePATTarget ( IN ULONG_PTR  Context)
static

Definition at line 61 of file patpge.c.

62{
63 ULONGLONG Pat;
64
66
67 /*
68 * Keep PAT0 and PAT4 as WB and PAT2/PAT6 as UC-minus. Replace the
69 * reset WT entries at PAT1 and PAT5 with WC. This is the same layout
70 * used by the AMD64 kernel.
71 */
72 Pat = (PAT_WB << 0) | (PAT_WC << 8) | (PAT_UCM << 16) | (PAT_UC << 24) |
73 (PAT_WB << 32) | (PAT_WC << 40) | (PAT_UCM << 48) | (PAT_UC << 56);
74
75 /* Invalidate cached translations and data before changing their types. */
78 __writemsr(MSR_PAT, Pat);
80
81 return 0;
82}
PPC_QUAL void __writemsr(const unsigned long Value)
Definition: intrin_ppc.h:748
#define PAT_UC
Definition: ketypes.h:281
#define MSR_PAT
Definition: ketypes.h:295
#define PAT_WB
Definition: ketypes.h:285
#define PAT_UCM
Definition: ketypes.h:286
#define PAT_WC
Definition: ketypes.h:282
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:361
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:523
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by KiInitializePAT().

◆ Ki386MapAddress()

BOOLEAN NTAPI Ki386MapAddress ( PLARGE_IDENTITY_MAP  IdentityMap,
ULONG_PTR  VirtualPtr,
PHYSICAL_ADDRESS  PhysicalPtr 
)

Definition at line 180 of file patpge.c.

183{
184 PHARDWARE_PTE Pde, Pte;
186
187 /* Allocate page directory on demand */
188 if (!IdentityMap->TopLevelDirectory)
189 {
190 IdentityMap->TopLevelDirectory = Ki386AllocateContiguousMemory(IdentityMap, 1, 1);
191 if (!IdentityMap->TopLevelDirectory) return FALSE;
192 }
193
194 /* Get PDE of VirtualPtr and make it writable and valid */
195 Pde = &IdentityMap->TopLevelDirectory[(VirtualPtr >> 22) & ((1 << PDE_BITS) - 1)];
196 if (!Ki386IdentityMapMakeValid(IdentityMap, Pde, &PageTable)) return FALSE;
197 Pde->Write = 1;
198
199 /* Get PTE of VirtualPtr, make it valid, and map PhysicalPtr there */
200 Pte = &PageTable[(VirtualPtr >> 12) & ((1 << PTE_BITS) - 1)];
201 Pte->Valid = 1;
202 Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT);
203
204 return TRUE;
205}
BOOLEAN NTAPI Ki386IdentityMapMakeValid(PLARGE_IDENTITY_MAP IdentityMap, PHARDWARE_PTE Pde, PHARDWARE_PTE *PageTable)
Definition: patpge.c:149
#define PDE_BITS
Definition: patpge.c:15
#define PTE_BITS
Definition: patpge.c:16
ULONG64 Write
Definition: mmtypes.h:67

Referenced by Ki386CreateIdentityMap().

◆ KiInitializePAT()

VOID NTAPI KiInitializePAT ( VOID  )

Definition at line 87 of file patpge.c.

88{
89 /* PAT values must be identical on every processor. */
91}
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
static ULONG_PTR NTAPI Ki386InitializePATTarget(IN ULONG_PTR Context)
Definition: patpge.c:61

Referenced by KiInitMachineDependent().