ReactOS  r73429
page.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/mm/powerpc/page.c
5  * PURPOSE: Low level memory managment manipulation
6  *
7  * PROGRAMMERS: David Welch (welch@cwcom.net)
8  * Revised for PowerPC by arty
9  */
10 
11 /* INCLUDES ***************************************************************/
12 
13 #include <ntoskrnl.h>
14 #include <ppcmmu/mmu.h>
15 //#define NDEBUG
16 #include <debug.h>
17 
18 #if defined (ALLOC_PRAGMA)
19 #pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory)
20 #endif
21 
22 /* GLOBALS *****************************************************************/
23 
24 #define HYPERSPACE_PAGEDIR_PTR ((PVOID)0xc0000000)
25 
26 #define PA_PRESENT (1ll<<63)
27 #define PA_USER (1ll<<62)
28 #define PA_ACCESSED 0x200
29 #define PA_DIRTY 0x100
30 #define PA_WT 0x20
31 #define PA_CD 0x10
32 #define PA_READWRITE 3
33 
34 #define HYPERSPACE (0xc0400000)
35 #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
36 
37 #define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
38 #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
39 
40 #if defined(__GNUC__)
41 #define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
42 #else
44 {
46  dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
47  return dummy;
48 }
49 #endif
50 
51 /* FUNCTIONS ***************************************************************/
52 
53 VOID
54 NTAPI
56 {
57  if (Address == (PVOID)0xffffffff)
58  {
59  __asm__("tlbsync");
60  }
61  else if (Address == (PVOID)0xfffffffe)
62  {
63  __asm__("tlbsync");
64  }
65  else
66  {
67  __asm__("tlbi %0" : "=r" (Address));
68  }
69 }
70 
71 VOID
73 {
74  __asm__("tlbi %0" : "=r" (Address));
75 }
76 
77 static ULONG
79 {
80  return MMU_ALL_RW; // XXX hack
81 }
82 
84 NTAPI
86  PEPROCESS Dest,
87  PPHYSICAL_ADDRESS DirectoryTableBase)
88 {
89  DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
90 
91  ASSERT(FALSE);
92 
93  return(STATUS_SUCCESS);
94 }
95 
96 BOOLEAN
97 NTAPI
100  IN PLARGE_INTEGER DirectoryTableBase)
101 {
102  ASSERT(FALSE);
103  return TRUE;
104 }
105 
106 VOID
107 NTAPI
109 {
111 
112  DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
113  Process, CurrentProcess);
114 
115  if (Process != NULL && Process != CurrentProcess)
116  {
117  KeAttachProcess(&Process->Pcb);
118  }
119 
120  if (Process)
121  {
122  DPRINT1("Revoking VSID %d\n", (paddr_t)Process->UniqueProcessId);
123  MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
124  }
125  else
126  {
127  DPRINT1("No vsid to revoke\n");
128  }
129 
130  if (Process != NULL && Process != CurrentProcess)
131  {
132  KeDetachProcess();
133  }
134 }
135 
136 VOID
137 NTAPI
139 {
140  MmDeletePageTable(Process, Address);
141 }
142 
143 PVOID
144 NTAPI
146 {
147  ppc_map_info_t info = { 0 };
148  info.proc = Process ? (int)Process->UniqueProcessId : 0;
149  info.addr = (vaddr_t)Addr;
150  MmuInqPage(&info, 1);
151  return (PVOID)info.phys;
152 }
153 
155 NTAPI
157  PVOID Address)
158 {
159  return((PFN_NUMBER)MmGetPhysicalAddressProcess(Process, Address) >> PAGE_SHIFT);
160 }
161 
162 VOID
163 NTAPI
165  BOOLEAN* WasDirty, PPFN_NUMBER Page)
166 /*
167  * FUNCTION: Delete a virtual mapping
168  */
169 {
170  ppc_map_info_t info = { 0 };
171 
172  DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
173  Process, Address, WasDirty, Page);
174 
175  info.proc = Process ? (int)Process->UniqueProcessId : 0;
176  info.addr = (vaddr_t)Address;
177  MmuInqPage(&info, 1);
178 
179  /*
180  * Return some information to the caller
181  */
182  if (WasDirty != NULL)
183  {
184  *WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
185  }
186  if (Page != NULL)
187  {
188  *Page = info.phys >> PAGE_SHIFT;
189  }
190 }
191 
192 VOID
193 NTAPI
195  SWAPENTRY* SwapEntry)
196 /*
197  * FUNCTION: Delete a virtual mapping
198  */
199 {
200  ppc_map_info_t info = { 0 };
201  /*
202  * Decrement the reference count for this page table.
203  */
204  if (Process != NULL &&
205  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
206  Address < MmSystemRangeStart)
207  {
208  PUSHORT Ptrc;
209 
210  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
211  MmFreePageTable(Process, Address);
212  }
213 
214  /*
215  * Return some information to the caller
216  */
217  MmuInqPage(&info, 1);
218  *SwapEntry = info.phys;
219 }
220 
221 BOOLEAN
222 NTAPI
224 {
225  ppc_map_info_t info = { 0 };
226  info.proc = Process ? (int)Process->UniqueProcessId : 0;
227  info.addr = (vaddr_t)Address;
228  MmuInqPage(&info, 1);
229  return !!(info.flags & MMU_PAGE_DIRTY);
230 }
231 
232 VOID
233 NTAPI
235 {
236 }
237 
238 VOID
239 NTAPI
241 {
242 }
243 
244 BOOLEAN
245 NTAPI
247 {
248  ppc_map_info_t info = { 0 };
249  info.proc = Process ? (int)Process->UniqueProcessId : 0;
250  info.addr = (vaddr_t)Address;
251  MmuInqPage(&info, 1);
252  return !!info.phys;
253 }
254 
256 {
257  return 0; // XXX arty
258 }
259 
260 BOOLEAN
261 NTAPI
263 {
264  ULONG Entry;
265  Entry = MmGetPageEntryForProcess(Process, Address);
266  return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
267 }
268 
269 NTSTATUS
270 NTAPI
272  PVOID Address,
273  SWAPENTRY SwapEntry)
274 {
275  if (Process == NULL && Address < MmSystemRangeStart)
276  {
277  DPRINT1("No process\n");
278  ASSERT(FALSE);
279  }
280  if (Process != NULL && Address >= MmSystemRangeStart)
281  {
282  DPRINT1("Setting kernel address with process context\n");
283  ASSERT(FALSE);
284  }
285  if (SwapEntry & (1 << 31))
286  {
287  ASSERT(FALSE);
288  }
289 
290  // XXX arty
291 
292  return(STATUS_SUCCESS);
293 }
294 
295 
296 NTSTATUS
297 NTAPI
299  PVOID Address,
300  ULONG flProtect,
301  PPFN_NUMBER Pages,
302  ULONG PageCount)
303 {
305  PVOID Addr;
306  ULONG i;
307  ppc_map_info_t info = { 0 };
308 
309  DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
310  Process, Address, flProtect, Pages, *Pages, PageCount);
311 
312  if (Process == NULL)
313  {
314  if (Address < MmSystemRangeStart)
315  {
316  DPRINT1("No process\n");
317  ASSERT(FALSE);
318  }
319  if (PageCount > 0x10000 ||
320  (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
321  {
322  DPRINT1("Page count to large\n");
323  ASSERT(FALSE);
324  }
325  }
326  else
327  {
328  if (Address >= MmSystemRangeStart)
329  {
330  DPRINT1("Setting kernel address with process context\n");
331  ASSERT(FALSE);
332  }
333  if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
334  (ULONG_PTR) Address / PAGE_SIZE + PageCount >
336  {
337  DPRINT1("Page Count to large\n");
338  ASSERT(FALSE);
339  }
340  }
341 
342  Attributes = ProtectToFlags(flProtect);
343  Addr = Address;
344 
345  for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
346  {
347  Process = PsGetCurrentProcess();
348  info.proc = ((Addr < MmSystemRangeStart) && Process) ?
349  (int)Process->UniqueProcessId : 0;
350  info.addr = (vaddr_t)Addr;
351  info.flags = Attributes;
352  MmuMapPage(&info, 1);
353  //(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
354  if (Address < MmSystemRangeStart &&
355  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
356  Attributes & PA_PRESENT)
357  {
358 #if 0
359  PUSHORT Ptrc;
360 
361  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
362 
363  Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
364 #endif
365  }
366  }
367  return(STATUS_SUCCESS);
368 }
369 
370 NTSTATUS
371 NTAPI
373  PVOID Address,
374  ULONG flProtect,
375  PPFN_NUMBER Pages,
376  ULONG PageCount)
377 {
378  ULONG i;
379 
380  for (i = 0; i < PageCount; i++)
381  {
382  if (!MmIsUsablePage(Pages[i]))
383  {
384  DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i]));
385  ASSERT(FALSE);
386  }
387  }
388 
389  return(MmCreateVirtualMappingUnsafe(Process,
390  Address,
391  flProtect,
392  Pages,
393  PageCount));
394 }
395 
396 ULONG
397 NTAPI
399 {
400  ULONG Protect = 0;
401  ppc_map_info_t info = { 0 };
402 
403  info.proc = Process ? (int)Process->UniqueProcessId : 0;
404  info.addr = (vaddr_t)Address;
405  MmuInqPage(&info, 1);
406 
407  if (!info.phys) { return PAGE_NOACCESS; }
408  if (!(info.flags & MMU_KMASK))
409  {
410  Protect |= PAGE_SYSTEM;
411  if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
412  Protect = PAGE_READWRITE;
413  else if (info.flags & MMU_KR)
414  Protect = PAGE_EXECUTE_READ;
415  }
416  else
417  {
418  if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
419  Protect = PAGE_READWRITE;
420  else
421  Protect = PAGE_EXECUTE_READ;
422  }
423  return(Protect);
424 }
425 
426 VOID
427 NTAPI
429 {
430  //ULONG Attributes = 0;
431 
432  DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
433  Process, Address, flProtect);
434 
435 #if 0
436  Attributes = ProtectToPTE(flProtect);
437 
438  Pt = MmGetPageTableForProcess(Process, Address, FALSE);
439  if (Pt == NULL)
440  {
441  ASSERT(FALSE);
442  }
444  MiFlushTlb(Pt, Address);
445 #endif
446 }
447 
448 VOID
450 NTAPI
452 {
453 }
454 
455 /* Create a simple, primitive mapping at the specified address on a new page */
457 {
459  ppc_map_info_t info = { 0 };
460  info.flags = MMU_KRW;
461  info.addr = (vaddr_t)PageAddr;
462  result = MmuMapPage(&info, 1) ? STATUS_SUCCESS : STATUS_NO_MEMORY;
463  return result;
464 }
465 
466 /* Use our primitive allocator */
468 {
470  DbgPrint("Got Page %x\n", Result);
471  return Result / PAGE_SIZE;
472 }
473 
474 /* EOF */
DWORD *typedef PVOID
Definition: winlogon.h:52
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:493
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
unsigned long proc
Definition: mmu.h:107
PVOID ULONG Address
Definition: oprghdlr.h:14
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: page.c:302
static ULONG ProtectToFlags(ULONG flProtect)
Definition: page.c:78
struct _Entry Entry
Definition: kefuncs.h:640
#define DbgPrint
Definition: loader.c:26
vaddr_t addr
Definition: mmu.h:108
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
NTSTATUS MmPPCCreatePrimitiveMapping(ULONG_PTR PageAddr)
Definition: page.c:456
VOID NTAPI MmDeletePageTable(PEPROCESS Process, PVOID Address)
Definition: page.c:108
static ULONG ProtectToPTE(ULONG flProtect)
Definition: page.c:152
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: page.c:451
PVOID NTAPI MmGetPhysicalAddressProcess(PEPROCESS Process, PVOID Addr)
Definition: page.c:145
unsigned long flags
Definition: mmu.h:107
#define TRUE
Definition: numbers.c:17
VOID NTAPI MiFlushTlbIpiRoutine(PVOID Address)
Definition: page.c:55
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:429
static void MmuRevokeVsid(int vsid, int mask)
Definition: mmu.h:247
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:368
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: page.c:138
_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:426
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:407
Definition: compobj.c:610
__asm__("\t.globl GetPhys\n""GetPhys:\t\n""mflr 0\n\t""stwu 0,-16(1)\n\t""mfmsr 5\n\t""andi. 6,5,0xffef\n\t""mtmsr 6\n\t""isync\n\t""sync\n\t""lwz 3,0(3)\n\t""mtmsr 5\n\t""isync\n\t""sync\n\t""lwz 0,0(1)\n\t""addi 1,1,16\n\t""mtlr 0\n\t""blr")
unsigned long paddr_t
Definition: mmu.h:89
static PMMPTE MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:329
HANDLE UniqueProcessId
Definition: pstypes.h:1119
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG * PPFN_NUMBER
Definition: ke.h:8
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
#define NULL
Definition: mystdio.h:57
unsigned long vaddr_t
Definition: mmu.h:90
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: page.c:501
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:321
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define MMU_PAGE_DIRTY
Definition: mmu.h:81
__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
Definition: page.c:43
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PA_PRESENT
Definition: page.c:26
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: page.c:377
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG PageProtection, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:512
#define MMU_KMASK
Definition: mmu.h:83
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:292
int64_t LONGLONG
Definition: typedefs.h:67
unsigned char BOOLEAN
#define PAGE_MASK(x)
Definition: page.c:49
ULONG CurrentProcess
Definition: shell.c:125
uint64_t ULONGLONG
Definition: typedefs.h:66
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
unsigned short * PUSHORT
Definition: retypes.h:2
PFN_NUMBER MmPPCPrimitiveAllocPage()
Definition: page.c:467
ULONGLONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:255
#define PAGE_SYSTEM
Definition: mm.h:84
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:566
#define PAGE_SIZE
Definition: env_spec_w32.h:49
KPROCESS Pcb
Definition: pstypes.h:1114
NTSTATUS NTAPI MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest, PPHYSICAL_ADDRESS DirectoryTableBase)
Definition: page.c:85
static int MmuMapPage(ppc_map_info_t *info, int count)
Definition: mmu.h:197
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: page.c:388
#define InterlockedExchange
Definition: armddk.h:54
#define MMU_KR
Definition: mmu.h:71
static void MmuInqPage(ppc_map_info_t *info, int count)
Definition: mmu.h:217
LONG NTSTATUS
Definition: DriverTester.h:11
#define PFN_TO_PTE(X)
Definition: page.c:38
#define MMU_KRW
Definition: mmu.h:76
#define ADDR_TO_PAGE_TABLE(v)
Definition: page.c:22
unsigned char dummy
Definition: maze.c:118
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:527
ULONG_PTR SWAPENTRY
Definition: mm.h:45
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
struct _EFI_FILE_HANDLE CHAR16 UINT64 UINT64 Attributes
Definition: acefiex.h:308
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: page.c:590
unsigned int * PULONG
Definition: retypes.h:1
#define MMU_ALL_RW
Definition: mmu.h:78
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define MMU_UW
Definition: mmu.h:74
#define FALSE
Definition: numbers.c:16
static paddr_t MmuGetPage()
Definition: mmu.h:252
#define MMU_KW
Definition: mmu.h:72
unsigned int ULONG
Definition: retypes.h:1
paddr_t phys
Definition: mmu.h:109
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define MMU_UR
Definition: mmu.h:73
#define PA_ACCESSED
Definition: page.c:28
#define PA_DIRTY
Definition: page.c:29
MM_AVL_TABLE VadRoot
Definition: pstypes.h:1305
GLuint64EXT * result
Definition: glext.h:11304
signed int * PLONG
Definition: retypes.h:5
#define MmSystemRangeStart
Definition: mm.h:25
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG Protect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:566
LONGLONG QuadPart
Definition: typedefs.h:113
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
#define PAGE_READWRITE
Definition: nt_native.h:1304
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29