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)
9 /* INCLUDES *******************************************************************/
15 #line 16 "ARM³::DEBUGSUP"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
20 #define KdpDprintf DPRINT
23 /* GLOBALS ********************************************************************/
25 PMMPTE MmDebugPte
= MiAddressToPte(MI_DEBUG_MAPPING
);
26 BOOLEAN MiDbgReadyForPhysical
= FALSE
;
28 /* FUNCTIONS ******************************************************************/
32 MmIsSessionAddress(IN PVOID Address
)
35 // No session space support yet
42 MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress
,
45 extern MMPTE ValidKernelPte
;
48 PVOID MappingBaseAddress
;
51 // Check if we are called too early
53 if (MiDbgReadyForPhysical
== FALSE
)
56 // The structures we require aren't initialized yet, fail
58 KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
59 "Address: 0x%I64x\n", PhysicalAddress
);
64 // FIXME: No support for cache flags yet
66 if ((Flags
& (MMDBG_COPY_CACHED
|
68 MMDBG_COPY_WRITE_COMBINED
)) != 0)
73 KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. "
74 "Flags: 0x%lx\n", Flags
& (MMDBG_COPY_CACHED
|
76 MMDBG_COPY_WRITE_COMBINED
));
81 // Save the base address of our mapping page
83 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
88 TempPte
= ValidKernelPte
;
91 // Convert physical address to PFN
93 Pfn
= (PFN_NUMBER
)(PhysicalAddress
>> PAGE_SHIFT
);
95 /* Check if this could be an I/O mapping */
96 if (!MiGetPfnEntry(Pfn
))
99 // FIXME: We don't support this yet
101 KdpDprintf("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 KdpDprintf("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 KdpDprintf("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 KdpDprintf("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 KdpDprintf("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 KdpDprintf("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