ReactOS  0.4.14-dev-991-g696cdc6
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",
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 {
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 {
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 &&
207  {
208  PUSHORT Ptrc;
209 
210  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
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;
266  return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
267 }
268 
269 NTSTATUS
270 NTAPI
272  PVOID Address,
273  SWAPENTRY SwapEntry)
274 {
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  {
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  {
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  {
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 &&
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 
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))
413  else if (info.flags & MMU_KR)
415  }
416  else
417  {
418  if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
420  else
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 
439  if (Pt == NULL)
440  {
441  ASSERT(FALSE);
442  }
444  MiFlushTlb(Pt, Address);
445 #endif
446 }
447 
448 VOID
449 INIT_FUNCTION
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;
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 */
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:495
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
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:627
#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
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:153
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: page.c:453
PVOID NTAPI MmGetPhysicalAddressProcess(PEPROCESS Process, PVOID Addr)
Definition: page.c:145
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI MiFlushTlbIpiRoutine(PVOID Address)
Definition: page.c:55
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:431
static void MmuRevokeVsid(int vsid, int mask)
Definition: mmu.h:247
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:370
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: page.c:138
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:409
unsigned long paddr_t
Definition: mmu.h:89
static PMMPTE MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:331
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG * PPFN_NUMBER
Definition: ke.h:8
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
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
__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:503
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:323
#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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define PA_PRESENT
Definition: page.c:26
_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:379
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG PageProtection, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:514
void * PVOID
Definition: retypes.h:9
#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
#define PAGE_MASK(x)
Definition: page.c:50
ULONG CurrentProcess
Definition: shell.c:125
uint64_t ULONGLONG
Definition: typedefs.h:66
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
PFN_NUMBER MmPPCPrimitiveAllocPage()
Definition: page.c:467
ULONGLONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:255
#define PAGE_SYSTEM
Definition: mm.h:86
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
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: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:390
#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
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#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:23
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:246
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: page.c:592
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
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 MMU_UR
Definition: mmu.h:73
#define PA_ACCESSED
Definition: page.c:28
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define PA_DIRTY
Definition: page.c:29
GLuint64EXT * result
Definition: glext.h:11304
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:568
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
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31