ReactOS  0.4.15-dev-1618-g9c8ed68
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 /* GLOBALS *****************************************************************/
19 
20 #define HYPERSPACE_PAGEDIR_PTR ((PVOID)0xc0000000)
21 
22 #define PA_PRESENT (1ll<<63)
23 #define PA_USER (1ll<<62)
24 #define PA_ACCESSED 0x200
25 #define PA_DIRTY 0x100
26 #define PA_WT 0x20
27 #define PA_CD 0x10
28 #define PA_READWRITE 3
29 
30 #define HYPERSPACE (0xc0400000)
31 #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
32 
33 #define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
34 #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
35 
36 #if defined(__GNUC__)
37 #define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
38 #else
40 {
42  dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
43  return dummy;
44 }
45 #endif
46 
47 /* FUNCTIONS ***************************************************************/
48 
49 VOID
50 NTAPI
52 {
53  if (Address == (PVOID)0xffffffff)
54  {
55  __asm__("tlbsync");
56  }
57  else if (Address == (PVOID)0xfffffffe)
58  {
59  __asm__("tlbsync");
60  }
61  else
62  {
63  __asm__("tlbi %0" : "=r" (Address));
64  }
65 }
66 
67 VOID
69 {
70  __asm__("tlbi %0" : "=r" (Address));
71 }
72 
73 static ULONG
75 {
76  return MMU_ALL_RW; // XXX hack
77 }
78 
80 NTAPI
82  PEPROCESS Dest,
83  PPHYSICAL_ADDRESS DirectoryTableBase)
84 {
85  DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
86 
87  ASSERT(FALSE);
88 
89  return(STATUS_SUCCESS);
90 }
91 
92 BOOLEAN
93 NTAPI
96  IN PLARGE_INTEGER DirectoryTableBase)
97 {
98  ASSERT(FALSE);
99  return TRUE;
100 }
101 
102 VOID
103 NTAPI
105 {
107 
108  DPRINT1("DeletePageTable: Process: %x CurrentProcess %x\n",
110 
111  if (Process != NULL && Process != CurrentProcess)
112  {
113  KeAttachProcess(&Process->Pcb);
114  }
115 
116  if (Process)
117  {
118  DPRINT1("Revoking VSID %d\n", (paddr_t)Process->UniqueProcessId);
119  MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
120  }
121  else
122  {
123  DPRINT1("No vsid to revoke\n");
124  }
125 
126  if (Process != NULL && Process != CurrentProcess)
127  {
128  KeDetachProcess();
129  }
130 }
131 
132 VOID
133 NTAPI
135 {
137 }
138 
139 PVOID
140 NTAPI
142 {
143  ppc_map_info_t info = { 0 };
144  info.proc = Process ? (int)Process->UniqueProcessId : 0;
145  info.addr = (vaddr_t)Addr;
146  MmuInqPage(&info, 1);
147  return (PVOID)info.phys;
148 }
149 
151 NTAPI
153  PVOID Address)
154 {
156 }
157 
158 VOID
159 NTAPI
161  BOOLEAN* WasDirty, PPFN_NUMBER Page)
162 /*
163  * FUNCTION: Delete a virtual mapping
164  */
165 {
166  ppc_map_info_t info = { 0 };
167 
168  DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
169  Process, Address, WasDirty, Page);
170 
171  info.proc = Process ? (int)Process->UniqueProcessId : 0;
172  info.addr = (vaddr_t)Address;
173  MmuInqPage(&info, 1);
174 
175  /*
176  * Return some information to the caller
177  */
178  if (WasDirty != NULL)
179  {
180  *WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
181  }
182  if (Page != NULL)
183  {
184  *Page = info.phys >> PAGE_SHIFT;
185  }
186 }
187 
188 VOID
189 NTAPI
191  SWAPENTRY* SwapEntry)
192 /*
193  * FUNCTION: Delete a virtual mapping
194  */
195 {
196  ppc_map_info_t info = { 0 };
197  /*
198  * Decrement the reference count for this page table.
199  */
200  if (Process != NULL &&
201  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
203  {
204  PUSHORT Ptrc;
205 
206  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
208  }
209 
210  /*
211  * Return some information to the caller
212  */
213  MmuInqPage(&info, 1);
214  *SwapEntry = info.phys;
215 }
216 
217 BOOLEAN
218 NTAPI
220 {
221  ppc_map_info_t info = { 0 };
222  info.proc = Process ? (int)Process->UniqueProcessId : 0;
223  info.addr = (vaddr_t)Address;
224  MmuInqPage(&info, 1);
225  return !!(info.flags & MMU_PAGE_DIRTY);
226 }
227 
228 VOID
229 NTAPI
231 {
232 }
233 
234 VOID
235 NTAPI
237 {
238 }
239 
240 BOOLEAN
241 NTAPI
243 {
244  ppc_map_info_t info = { 0 };
245  info.proc = Process ? (int)Process->UniqueProcessId : 0;
246  info.addr = (vaddr_t)Address;
247  MmuInqPage(&info, 1);
248  return !!info.phys;
249 }
250 
252 {
253  return 0; // XXX arty
254 }
255 
256 BOOLEAN
257 NTAPI
259 {
260  ULONG Entry;
262  return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
263 }
264 
265 NTSTATUS
266 NTAPI
268  PVOID Address,
269  SWAPENTRY SwapEntry)
270 {
272  {
273  DPRINT1("No process\n");
274  ASSERT(FALSE);
275  }
276  if (Process != NULL && Address >= MmSystemRangeStart)
277  {
278  DPRINT1("Setting kernel address with process context\n");
279  ASSERT(FALSE);
280  }
281  if (SwapEntry & (1 << 31))
282  {
283  ASSERT(FALSE);
284  }
285 
286  // XXX arty
287 
288  return(STATUS_SUCCESS);
289 }
290 
291 
292 NTSTATUS
293 NTAPI
295  PVOID Address,
296  ULONG flProtect,
297  PPFN_NUMBER Pages,
298  ULONG PageCount)
299 {
301  PVOID Addr;
302  ULONG i;
303  ppc_map_info_t info = { 0 };
304 
305  DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
306  Process, Address, flProtect, Pages, *Pages, PageCount);
307 
308  if (Process == NULL)
309  {
311  {
312  DPRINT1("No process\n");
313  ASSERT(FALSE);
314  }
315  if (PageCount > 0x10000 ||
316  (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
317  {
318  DPRINT1("Page count to large\n");
319  ASSERT(FALSE);
320  }
321  }
322  else
323  {
325  {
326  DPRINT1("Setting kernel address with process context\n");
327  ASSERT(FALSE);
328  }
329  if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
330  (ULONG_PTR) Address / PAGE_SIZE + PageCount >
332  {
333  DPRINT1("Page Count to large\n");
334  ASSERT(FALSE);
335  }
336  }
337 
338  Attributes = ProtectToFlags(flProtect);
339  Addr = Address;
340 
341  for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
342  {
344  info.proc = ((Addr < MmSystemRangeStart) && Process) ?
345  (int)Process->UniqueProcessId : 0;
346  info.addr = (vaddr_t)Addr;
347  info.flags = Attributes;
348  MmuMapPage(&info, 1);
349  //(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
350  if (Address < MmSystemRangeStart &&
351  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
353  {
354 #if 0
355  PUSHORT Ptrc;
356 
357  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
358 
359  Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
360 #endif
361  }
362  }
363  return(STATUS_SUCCESS);
364 }
365 
366 NTSTATUS
367 NTAPI
369  PVOID Address,
370  ULONG flProtect,
371  PPFN_NUMBER Pages,
372  ULONG PageCount)
373 {
374  ULONG i;
375 
376  for (i = 0; i < PageCount; i++)
377  {
378  if (!MmIsUsablePage(Pages[i]))
379  {
380  DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i]));
381  ASSERT(FALSE);
382  }
383  }
384 
386  Address,
387  flProtect,
388  Pages,
389  PageCount));
390 }
391 
392 ULONG
393 NTAPI
395 {
396  ULONG Protect = 0;
397  ppc_map_info_t info = { 0 };
398 
399  info.proc = Process ? (int)Process->UniqueProcessId : 0;
400  info.addr = (vaddr_t)Address;
401  MmuInqPage(&info, 1);
402 
403  if (!info.phys) { return PAGE_NOACCESS; }
404  if (!(info.flags & MMU_KMASK))
405  {
406  Protect |= PAGE_SYSTEM;
407  if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
409  else if (info.flags & MMU_KR)
411  }
412  else
413  {
414  if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
416  else
418  }
419  return(Protect);
420 }
421 
422 VOID
423 NTAPI
425 {
426  //ULONG Attributes = 0;
427 
428  DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
429  Process, Address, flProtect);
430 
431 #if 0
432  Attributes = ProtectToPTE(flProtect);
433 
435  if (Pt == NULL)
436  {
437  ASSERT(FALSE);
438  }
440  MiFlushTlb(Pt, Address);
441 #endif
442 }
443 
444 CODE_SEG("INIT")
445 VOID
446 NTAPI
448 {
449 }
450 
451 /* Create a simple, primitive mapping at the specified address on a new page */
453 {
455  ppc_map_info_t info = { 0 };
456  info.flags = MMU_KRW;
457  info.addr = (vaddr_t)PageAddr;
459  return result;
460 }
461 
462 /* Use our primitive allocator */
464 {
466  DbgPrint("Got Page %x\n", Result);
467  return Result / PAGE_SIZE;
468 }
469 
470 /* EOF */
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:462
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: page.c:292
static ULONG ProtectToFlags(ULONG flProtect)
Definition: page.c:74
struct _Entry Entry
Definition: kefuncs.h:627
GLuint64EXT * result
Definition: glext.h:11304
#define DbgPrint
Definition: loader.c:25
_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 TRUE
Definition: types.h:120
NTSTATUS MmPPCCreatePrimitiveMapping(ULONG_PTR PageAddr)
Definition: page.c:452
VOID NTAPI MmDeletePageTable(PEPROCESS Process, PVOID Address)
Definition: page.c:104
static ULONG ProtectToPTE(ULONG flProtect)
Definition: page.c:149
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: page.c:420
PVOID NTAPI MmGetPhysicalAddressProcess(PEPROCESS Process, PVOID Addr)
Definition: page.c:141
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI MiFlushTlbIpiRoutine(PVOID Address)
Definition: page.c:51
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:398
static void MmuRevokeVsid(int vsid, int mask)
Definition: mmu.h:247
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:337
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:278
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: page.c:134
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:376
unsigned long paddr_t
Definition: mmu.h:89
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
__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 vaddr_t
Definition: mmu.h:90
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: page.c:486
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:313
#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:39
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
#define PA_PRESENT
Definition: page.c:22
_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
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: page.c:346
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG PageProtection, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:526
void * PVOID
Definition: retypes.h:9
#define MMU_KMASK
Definition: mmu.h:83
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:282
int64_t LONGLONG
Definition: typedefs.h:68
#define PAGE_MASK(x)
Definition: page.c:46
ULONG CurrentProcess
Definition: shell.c:125
#define ASSERT(a)
Definition: mode.c:45
uint64_t ULONGLONG
Definition: typedefs.h:67
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
PFN_NUMBER MmPPCPrimitiveAllocPage()
Definition: page.c:463
ULONGLONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:251
CODE_SEG("INIT")
Definition: fsrtlpc.c:19
#define PAGE_SYSTEM
Definition: mm.h:86
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:618
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS NTAPI MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest, PPHYSICAL_ADDRESS DirectoryTableBase)
Definition: page.c:81
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:357
#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
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:206
#define PFN_TO_PTE(X)
Definition: page.c:34
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MMU_KRW
Definition: mmu.h:76
#define ADDR_TO_PAGE_TABLE(v)
Definition: page.c:19
unsigned char dummy
Definition: maze.c:118
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:579
ULONG_PTR SWAPENTRY
Definition: mm.h:47
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: page.c:604
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#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
static paddr_t MmuGetPage()
Definition: mmu.h:252
#define MMU_KW
Definition: mmu.h:72
unsigned int ULONG
Definition: retypes.h:1
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define STATUS_SUCCESS
Definition: shellext.h:65
#define MMU_UR
Definition: mmu.h:73
#define PA_ACCESSED
Definition: page.c:24
#define PA_DIRTY
Definition: page.c:25
signed int * PLONG
Definition: retypes.h:5
#define MmSystemRangeStart
Definition: mm.h:32
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG Protect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:580
unsigned short * PUSHORT
Definition: retypes.h:2
base of all file and directory entries
Definition: entries.h:82
#define PAGE_READWRITE
Definition: nt_native.h:1304
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31