2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/mm/mmdbg.c
5 * PURPOSE: Memory Manager support routines for the Kernel Debugger
6 * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org)
9 /* INCLUDES *******************************************************************/
12 #include "ARM3/miarm.h"
17 #define KDDBGPRINT KdpDprintf
19 #define KDDBGPRINT if (0) KdpDprintf
22 /* GLOBALS ********************************************************************/
24 PVOID MiDebugMapping
= MI_DEBUG_MAPPING
;
25 PMMPTE MmDebugPte
= NULL
;
27 /* FUNCTIONS ******************************************************************/
31 MmIsSessionAddress(IN PVOID Address
)
34 // No session space support yet
41 MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress
,
46 PVOID MappingBaseAddress
;
49 // Check if we are called too early
51 if (MmDebugPte
== NULL
)
54 // The structures we require aren't initialized yet, fail
56 KDDBGPRINT("MiDbgTranslatePhysicalAddress called too early! "
57 "Address: 0x%I64x\n", PhysicalAddress
);
62 // FIXME: No support for cache flags yet
64 if ((Flags
& (MMDBG_COPY_CACHED
|
66 MMDBG_COPY_WRITE_COMBINED
)) != 0)
71 KDDBGPRINT("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. "
72 "Flags: 0x%lx\n", Flags
& (MMDBG_COPY_CACHED
|
74 MMDBG_COPY_WRITE_COMBINED
));
79 // Save the base address of our mapping page
81 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
86 TempPte
= HyperTemplatePte
;
89 // Convert physical address to PFN
91 Pfn
= (PFN_NUMBER
)(PhysicalAddress
>> PAGE_SHIFT
);
94 // Check if this could be an I/O mapping
96 if (Pfn
> MmHighestPhysicalPage
)
99 // FIXME: We don't support this yet
101 KDDBGPRINT("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
102 "PFN: 0x%I64x\n", (ULONG64
)Pfn
);
108 // Set the PFN in the PTE
110 TempPte
.u
.Hard
.PageFrameNumber
= Pfn
;
114 // Map the PTE and invalidate its TLB entry
116 *MmDebugPte
= TempPte
;
117 KeInvalidateTlbEntry(MappingBaseAddress
);
120 // Calculate and return the virtual offset into our mapping page
122 return (PVOID
)((ULONG_PTR
)MappingBaseAddress
+
123 BYTE_OFFSET(PhysicalAddress
));
128 MiDbgUnTranslatePhysicalAddress(VOID
)
130 PVOID MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
133 // The address must still be valid at this point
135 ASSERT(MmIsAddressValid(MappingBaseAddress
));
138 // Clear the mapping PTE and invalidate its TLB entry
140 MmDebugPte
->u
.Long
= 0;
141 KeInvalidateTlbEntry(MappingBaseAddress
);
146 MmDbgCopyMemory(IN ULONG64 Address
,
155 // No local kernel debugging support yet, so don't worry about locking
157 ASSERT(Flags
& MMDBG_COPY_UNSAFE
);
160 // We only handle 1, 2, 4 and 8 byte requests
165 (Size
!= MMDBG_COPY_MAX_SIZE
))
168 // Invalid size, fail
170 KDDBGPRINT("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size
);
171 return STATUS_INVALID_PARAMETER_3
;
175 // The copy must be aligned
177 if ((Address
& (Size
- 1)) != 0)
182 KDDBGPRINT("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
184 return STATUS_INVALID_PARAMETER_3
;
188 // Check if this is physical or virtual copy
190 if (Flags
& MMDBG_COPY_PHYSICAL
)
193 // Physical: translate and map it to our mapping space
195 TargetAddress
= MiDbgTranslatePhysicalAddress(Address
, Flags
);
198 // Check if translation failed
205 KDDBGPRINT("MmDbgCopyMemory: Failed to Translate Physical Address "
207 return STATUS_UNSUCCESSFUL
;
211 // The address we received must be valid!
213 ASSERT(MmIsAddressValid(TargetAddress
));
218 // Virtual; truncate it to avoid casts later down
220 TargetAddress
= (PVOID
)(ULONG_PTR
)Address
;
223 // Check if the address is invalid
225 if (!MmIsAddressValid(TargetAddress
))
230 KDDBGPRINT("MmDbgCopyMemory: Failing %s for invalid "
231 "Virtual Address 0x%p\n",
232 Flags
& MMDBG_COPY_WRITE
? "write" : "read",
234 return STATUS_UNSUCCESSFUL
;
238 // No session space support yet
240 ASSERT(MmIsSessionAddress(TargetAddress
) == FALSE
);
244 // If we are going to write to the address then make sure it is writeable too
246 if ((Flags
& MMDBG_COPY_WRITE
) &&
247 (!MI_IS_PAGE_WRITEABLE(MiAddressToPte(TargetAddress
))))
250 // Check if we mapped anything
252 if (Flags
& MMDBG_COPY_PHYSICAL
)
255 // Get rid of the mapping
257 MiDbgUnTranslatePhysicalAddress();
263 // FIXME: We should attempt to override the write protection instead of
266 KDDBGPRINT("MmDbgCopyMemory: Failing Write for Protected Address 0x%p\n",
268 return STATUS_UNSUCCESSFUL
;
272 // Use SEH to try to catch anything else somewhat cleanly
277 // Check if this is read or write
279 if (Flags
& MMDBG_COPY_WRITE
)
284 RtlCopyMemory(TargetAddress
,
293 RtlCopyMemory(Buffer
,
301 Status
= STATUS_SUCCESS
;
303 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
306 // Get the exception code
308 Status
= _SEH2_GetExceptionCode();
313 // Get rid of the mapping if this was a physical copy
315 if (Flags
& MMDBG_COPY_PHYSICAL
)
318 // Unmap and flush it
320 MiDbgUnTranslatePhysicalAddress();
324 // Return status to caller