ReactOS  r76032
mmdbg.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/mmdbg.c
5  * PURPOSE: Memory Manager support routines for the Kernel Debugger
6  * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
17 
18 #ifndef _WINKD_
19 #define KdpDprintf DPRINT
20 #elif defined(NDEBUG)
21 #define KdpDprintf(...)
22 #endif
23 
24 BOOLEAN
25 NTAPI
28 );
29 
30 /* GLOBALS ********************************************************************/
31 
34 
35 /* FUNCTIONS ******************************************************************/
36 
37 PVOID
38 NTAPI
40  IN ULONG Flags)
41 {
42  PFN_NUMBER Pfn;
43  MMPTE TempPte;
44  PVOID MappingBaseAddress;
45 
46  /* Check if we are called too early */
47  if (MmDebugPte == NULL)
48  {
49  /* The structures we require aren't initialized yet, fail */
50  KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
51  "Address: 0x%I64x\n",
52  PhysicalAddress);
53  return NULL;
54  }
55 
56  /* FIXME: No support for cache flags yet */
57  if ((Flags & (MMDBG_COPY_CACHED |
60  {
61  /* Fail */
62  KdpDprintf("MiDbgTranslatePhysicalAddress: Cache flags not yet supported. "
63  "Flags: 0x%lx\n",
64  Flags & (MMDBG_COPY_CACHED |
67  return NULL;
68  }
69 
70  /* Save the base address of our mapping page */
71  MappingBaseAddress = MiPteToAddress(MmDebugPte);
72 
73  /* Get the template */
74  TempPte = ValidKernelPte;
75 
76  /* Convert physical address to PFN */
77  Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT);
78 
79  /* Check if this could be an I/O mapping */
80  if (!MiGetPfnEntry(Pfn))
81  {
82  /* FIXME: We don't support this yet */
83  KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
84  "PFN: 0x%I64x\n",
85  (ULONG64)Pfn);
86  return NULL;
87  }
88  else
89  {
90  /* Set the PFN in the PTE */
91  TempPte.u.Hard.PageFrameNumber = Pfn;
92  }
93 
94  /* Map the PTE and invalidate its TLB entry */
95  *MmDebugPte = TempPte;
96  KeInvalidateTlbEntry(MappingBaseAddress);
97 
98  /* Calculate and return the virtual offset into our mapping page */
99  return (PVOID)((ULONG_PTR)MappingBaseAddress +
100  BYTE_OFFSET(PhysicalAddress));
101 }
102 
103 VOID
104 NTAPI
106 {
107  PVOID MappingBaseAddress;
108 
109  /* The address must still be valid at this point */
110  MappingBaseAddress = MiPteToAddress(MmDebugPte);
111  ASSERT(MmIsAddressValid(MappingBaseAddress));
112 
113  /* Clear the mapping PTE and invalidate its TLB entry */
114  MmDebugPte->u.Long = 0;
115  KeInvalidateTlbEntry(MappingBaseAddress);
116 }
117 
118 
119 //
120 // We handle 8-byte requests at most
121 //
123 
124 NTSTATUS
125 NTAPI
127  IN PVOID Buffer,
128  IN ULONG Size,
129  IN ULONG Flags)
130 {
133  PMMPTE PointerPte;
134  PVOID CopyDestination, CopySource;
135 
136  /* No local kernel debugging support yet, so don't worry about locking */
137  ASSERT(Flags & MMDBG_COPY_UNSAFE);
138 
139  /* We only handle 1, 2, 4 and 8 byte requests */
140  if ((Size != 1) &&
141  (Size != 2) &&
142  (Size != 4) &&
143  (Size != 8))
144  {
145  /* Invalid size, fail */
146  KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
147  Size);
149  }
150 
151  /* The copy must be aligned */
152  if ((Address & (Size - 1)) != 0)
153  {
154  /* Not allowing unaligned access */
155  KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
156  Address,
157  Size);
159  }
160 
161  /* Check for physical or virtual copy */
162  if (Flags & MMDBG_COPY_PHYSICAL)
163  {
164  /* Physical: translate and map it to our mapping space */
165  TargetAddress = MiDbgTranslatePhysicalAddress(Address,
166  Flags);
167 
168  /* Check if translation failed */
169  if (!TargetAddress)
170  {
171  /* Fail */
172  KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
173  Address);
174  return STATUS_UNSUCCESSFUL;
175  }
176 
177  /* The address we received must be valid! */
178  ASSERT(MmIsAddressValid(TargetAddress));
179  }
180  else
181  {
182  /* Virtual; truncate it to avoid casts later down */
183  TargetAddress = (PVOID)(ULONG_PTR)Address;
184 
185  /* Make sure address is valid */
186  if (!MmIsAddressValid(TargetAddress))
187  {
188  /* Fail */
189  KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
190  Flags & MMDBG_COPY_WRITE ? "write" : "read",
191  TargetAddress);
192  return STATUS_UNSUCCESSFUL;
193  }
194 
195  /* Not handling session space correctly yet */
196  if (MmIsSessionAddress(TargetAddress))
197  {
198  /* FIXME */
199  }
200 
201  /* If we are going to write to the address, then check if its writable */
202  PointerPte = MiAddressToPte(TargetAddress);
203  if ((Flags & MMDBG_COPY_WRITE) &&
204  (!MI_IS_PAGE_WRITEABLE(PointerPte)))
205  {
206  /* Not writable, we need to do a physical copy */
207  Flags |= MMDBG_COPY_PHYSICAL;
208 
209  /* Calculate the physical address */
210  PhysicalAddress = PointerPte->u.Hard.PageFrameNumber << PAGE_SHIFT;
211  PhysicalAddress += BYTE_OFFSET(Address);
212 
213  /* Translate the physical address */
214  TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress,
215  Flags);
216 
217  /* Check if translation failed */
218  if (!TargetAddress)
219  {
220  /* Fail */
221  KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
222  PhysicalAddress,
223  Address);
224  return STATUS_UNSUCCESSFUL;
225  }
226  }
227  }
228 
229  /* Check what kind of operation this is */
230  if (Flags & MMDBG_COPY_WRITE)
231  {
232  /* Write */
233  CopyDestination = TargetAddress;
234  CopySource = Buffer;
235  }
236  else
237  {
238  /* Read */
239  CopyDestination = Buffer;
240  CopySource = TargetAddress;
241  }
242 
243  /* Do the copy */
244  switch (Size)
245  {
246  case 1:
247 
248  /* 1 byte */
249  *(PUCHAR)CopyDestination = *(PUCHAR)CopySource;
250  break;
251 
252  case 2:
253 
254  /* 2 bytes */
255  *(PUSHORT)CopyDestination = *(PUSHORT)CopySource;
256  break;
257 
258  case 4:
259 
260  /* 4 bytes */
261  *(PULONG)CopyDestination = *(PULONG)CopySource;
262  break;
263 
264  case 8:
265 
266  /* 8 bytes */
267  *(PULONGLONG)CopyDestination = *(PULONGLONG)CopySource;
268  break;
269 
270  /* Size is sanitized above */
272  }
273 
274  /* Get rid of the mapping if this was a physical copy */
275  if (Flags & MMDBG_COPY_PHYSICAL)
276  {
277  /* Unmap and flush it */
279  }
280 
281  /* And we are done */
282  return STATUS_SUCCESS;
283 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define DEFAULT_UNREACHABLE
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
PVOID NTAPI MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, IN ULONG Flags)
Definition: mmdbg.c:39
PVOID ULONG Address
Definition: oprghdlr.h:14
C_ASSERT(MMDBG_COPY_MAX_SIZE==8)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
return STATUS_SUCCESS
Definition: btrfs.c:2664
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER _Outptr_ PVOID * TargetAddress
Definition: iotypes.h:997
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID NTAPI MiDbgUnTranslatePhysicalAddress(VOID)
Definition: mmdbg.c:105
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
uint64_t ULONG64
Definition: typedefs.h:65
smooth NULL
Definition: ftsmooth.c:557
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
Definition: bufpool.h:45
#define MMDBG_COPY_WRITE
Definition: mm.h:51
UINTN Size
Definition: acefiex.h:555
#define MI_DEBUG_MAPPING
Definition: mm.h:22
unsigned char BOOLEAN
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:177
#define MMDBG_COPY_UNCACHED
Definition: mm.h:55
unsigned short * PUSHORT
Definition: retypes.h:2
PMMPTE MmDebugPte
Definition: mmdbg.c:33
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
UINTN VOID * Buffer
Definition: acefiex.h:370
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
#define MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:96
PVOID MiDebugMapping
Definition: mmdbg.c:32
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:873
ULONG_PTR Long
Definition: mmtypes.h:215
#define MMDBG_COPY_WRITE_COMBINED
Definition: mm.h:56
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
LONG NTSTATUS
Definition: DriverTester.h:11
#define MMDBG_COPY_PHYSICAL
Definition: mm.h:52
#define MMDBG_COPY_UNSAFE
Definition: mm.h:53
#define MMDBG_COPY_MAX_SIZE
Definition: mm.h:61
unsigned int * PULONG
Definition: retypes.h:1
BOOLEAN NTAPI MmIsSessionAddress(IN PVOID Address)
Definition: session.c:49
#define KdpDprintf
Definition: mmdbg.c:19
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:382
#define MMDBG_COPY_CACHED
Definition: mm.h:54
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2072 u
#define BYTE_OFFSET(Va)
NTSTATUS NTAPI MmDbgCopyMemory(IN ULONG64 Address, IN PVOID Buffer, IN ULONG Size, IN ULONG Flags)
Definition: mmdbg.c:126