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
,
47 PVOID MappingBaseAddress
;
50 // Check if we are called too early
52 if (MiDbgReadyForPhysical
== FALSE
)
55 // The structures we require aren't initialized yet, fail
57 KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
58 "Address: 0x%I64x\n", PhysicalAddress
);
63 // FIXME: No support for cache flags yet
65 if ((Flags
& (MMDBG_COPY_CACHED
|
67 MMDBG_COPY_WRITE_COMBINED
)) != 0)
72 KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. "
73 "Flags: 0x%lx\n", Flags
& (MMDBG_COPY_CACHED
|
75 MMDBG_COPY_WRITE_COMBINED
));
80 // Save the base address of our mapping page
82 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
87 TempPte
= ValidKernelPte
;
90 // Convert physical address to PFN
92 Pfn
= (PFN_NUMBER
)(PhysicalAddress
>> PAGE_SHIFT
);
94 /* Check if this could be an I/O mapping */
95 if (!MiGetPfnEntry(Pfn
))
98 // FIXME: We don't support this yet
100 KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
101 "PFN: 0x%I64x\n", (ULONG64
)Pfn
);
107 // Set the PFN in the PTE
109 TempPte
.u
.Hard
.PageFrameNumber
= Pfn
;
113 // Map the PTE and invalidate its TLB entry
115 *MmDebugPte
= TempPte
;
116 KeInvalidateTlbEntry(MappingBaseAddress
);
119 // Calculate and return the virtual offset into our mapping page
121 return (PVOID
)((ULONG_PTR
)MappingBaseAddress
+
122 BYTE_OFFSET(PhysicalAddress
));
127 MiDbgUnTranslatePhysicalAddress(VOID
)
129 PVOID MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
132 // The address must still be valid at this point
134 ASSERT(MmIsAddressValid(MappingBaseAddress
));
137 // Clear the mapping PTE and invalidate its TLB entry
139 MmDebugPte
->u
.Long
= 0;
140 KeInvalidateTlbEntry(MappingBaseAddress
);
145 MmDbgCopyMemory(IN ULONG64 Address
,
154 // No local kernel debugging support yet, so don't worry about locking
156 ASSERT(Flags
& MMDBG_COPY_UNSAFE
);
159 // We only handle 1, 2, 4 and 8 byte requests
164 (Size
!= MMDBG_COPY_MAX_SIZE
))
167 // Invalid size, fail
169 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size
);
170 return STATUS_INVALID_PARAMETER_3
;
174 // The copy must be aligned
176 if ((Address
& (Size
- 1)) != 0)
181 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
183 return STATUS_INVALID_PARAMETER_3
;
187 // Check if this is physical or virtual copy
189 if (Flags
& MMDBG_COPY_PHYSICAL
)
192 // Physical: translate and map it to our mapping space
194 TargetAddress
= MiDbgTranslatePhysicalAddress(Address
, Flags
);
197 // Check if translation failed
204 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address "
206 return STATUS_UNSUCCESSFUL
;
210 // The address we received must be valid!
212 ASSERT(MmIsAddressValid(TargetAddress
));
217 // Virtual; truncate it to avoid casts later down
219 TargetAddress
= (PVOID
)(ULONG_PTR
)Address
;
222 // Check if the address is invalid
224 if (!MmIsAddressValid(TargetAddress
))
229 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid "
230 "Virtual Address 0x%p\n",
231 Flags
& MMDBG_COPY_WRITE
? "write" : "read",
233 return STATUS_UNSUCCESSFUL
;
237 // No session space support yet
239 ASSERT(MmIsSessionAddress(TargetAddress
) == FALSE
);
243 // If we are going to write to the address then make sure it is writeable too
245 if ((Flags
& MMDBG_COPY_WRITE
) &&
246 (!MI_IS_PAGE_WRITEABLE(MiAddressToPte(TargetAddress
))))
249 // Check if we mapped anything
251 if (Flags
& MMDBG_COPY_PHYSICAL
)
254 // Get rid of the mapping
256 MiDbgUnTranslatePhysicalAddress();
262 // FIXME: We should attempt to override the write protection instead of
265 KdpDprintf("MmDbgCopyMemory: Failing Write for Protected Address 0x%p\n",
267 return STATUS_UNSUCCESSFUL
;
271 // Use SEH to try to catch anything else somewhat cleanly
276 // Check if this is read or write
278 if (Flags
& MMDBG_COPY_WRITE
)
283 RtlCopyMemory(TargetAddress
,
292 RtlCopyMemory(Buffer
,
300 Status
= STATUS_SUCCESS
;
302 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
305 // Get the exception code
307 Status
= _SEH2_GetExceptionCode();
312 // Get rid of the mapping if this was a physical copy
314 if (Flags
& MMDBG_COPY_PHYSICAL
)
317 // Unmap and flush it
319 MiDbgUnTranslatePhysicalAddress();
323 // Return status to caller