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"
16 /* GLOBALS ********************************************************************/
18 PMMPTE MmDebugPte
= MiAddressToPte(MI_DEBUG_MAPPING
);
19 BOOLEAN MiDbgReadyForPhysical
= FALSE
;
21 /* FUNCTIONS ******************************************************************/
25 MmIsSessionAddress(IN PVOID Address
)
28 // No session space support yet
35 MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress
,
40 PVOID MappingBaseAddress
;
43 // Check if we are called too early
45 if (MiDbgReadyForPhysical
== FALSE
)
48 // The structures we require aren't initialized yet, fail
50 KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
51 "Address: 0x%I64x\n", PhysicalAddress
);
56 // FIXME: No support for cache flags yet
58 if ((Flags
& (MMDBG_COPY_CACHED
|
60 MMDBG_COPY_WRITE_COMBINED
)) != 0)
65 KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. "
66 "Flags: 0x%lx\n", Flags
& (MMDBG_COPY_CACHED
|
68 MMDBG_COPY_WRITE_COMBINED
));
73 // Save the base address of our mapping page
75 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
80 TempPte
= HyperTemplatePte
;
83 // Convert physical address to PFN
85 Pfn
= (PFN_NUMBER
)(PhysicalAddress
>> PAGE_SHIFT
);
88 // Check if this could be an I/O mapping
90 if (Pfn
> MmHighestPhysicalPage
)
93 // FIXME: We don't support this yet
95 KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
96 "PFN: 0x%I64x\n", (ULONG64
)Pfn
);
102 // Set the PFN in the PTE
104 TempPte
.u
.Hard
.PageFrameNumber
= Pfn
;
108 // Map the PTE and invalidate its TLB entry
110 *MmDebugPte
= TempPte
;
111 KeInvalidateTlbEntry(MappingBaseAddress
);
114 // Calculate and return the virtual offset into our mapping page
116 return (PVOID
)((ULONG_PTR
)MappingBaseAddress
+
117 BYTE_OFFSET(PhysicalAddress
));
122 MiDbgUnTranslatePhysicalAddress(VOID
)
124 PVOID MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
127 // The address must still be valid at this point
129 ASSERT(MmIsAddressValid(MappingBaseAddress
));
132 // Clear the mapping PTE and invalidate its TLB entry
134 MmDebugPte
->u
.Long
= 0;
135 KeInvalidateTlbEntry(MappingBaseAddress
);
140 MmDbgCopyMemory(IN ULONG64 Address
,
149 // No local kernel debugging support yet, so don't worry about locking
151 ASSERT(Flags
& MMDBG_COPY_UNSAFE
);
154 // We only handle 1, 2, 4 and 8 byte requests
159 (Size
!= MMDBG_COPY_MAX_SIZE
))
162 // Invalid size, fail
164 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size
);
165 return STATUS_INVALID_PARAMETER_3
;
169 // The copy must be aligned
171 if ((Address
& (Size
- 1)) != 0)
176 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
178 return STATUS_INVALID_PARAMETER_3
;
182 // Check if this is physical or virtual copy
184 if (Flags
& MMDBG_COPY_PHYSICAL
)
187 // Physical: translate and map it to our mapping space
189 TargetAddress
= MiDbgTranslatePhysicalAddress(Address
, Flags
);
192 // Check if translation failed
199 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address "
201 return STATUS_UNSUCCESSFUL
;
205 // The address we received must be valid!
207 ASSERT(MmIsAddressValid(TargetAddress
));
212 // Virtual; truncate it to avoid casts later down
214 TargetAddress
= (PVOID
)(ULONG_PTR
)Address
;
217 // Check if the address is invalid
219 if (!MmIsAddressValid(TargetAddress
))
224 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid "
225 "Virtual Address 0x%p\n",
226 Flags
& MMDBG_COPY_WRITE
? "write" : "read",
228 return STATUS_UNSUCCESSFUL
;
232 // No session space support yet
234 ASSERT(MmIsSessionAddress(TargetAddress
) == FALSE
);
238 // If we are going to write to the address then make sure it is writeable too
240 if ((Flags
& MMDBG_COPY_WRITE
) &&
241 (!MI_IS_PAGE_WRITEABLE(MiAddressToPte(TargetAddress
))))
244 // Check if we mapped anything
246 if (Flags
& MMDBG_COPY_PHYSICAL
)
249 // Get rid of the mapping
251 MiDbgUnTranslatePhysicalAddress();
257 // FIXME: We should attempt to override the write protection instead of
260 KdpDprintf("MmDbgCopyMemory: Failing Write for Protected Address 0x%p\n",
262 return STATUS_UNSUCCESSFUL
;
266 // Use SEH to try to catch anything else somewhat cleanly
271 // Check if this is read or write
273 if (Flags
& MMDBG_COPY_WRITE
)
278 RtlCopyMemory(TargetAddress
,
287 RtlCopyMemory(Buffer
,
295 Status
= STATUS_SUCCESS
;
297 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
300 // Get the exception code
302 Status
= _SEH2_GetExceptionCode();
307 // Get rid of the mapping if this was a physical copy
309 if (Flags
& MMDBG_COPY_PHYSICAL
)
312 // Unmap and flush it
314 MiDbgUnTranslatePhysicalAddress();
318 // Return status to caller