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 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
19 #define KdpDprintf DPRINT
21 #define KdpDprintf(...)
30 /* GLOBALS ********************************************************************/
32 PVOID MiDebugMapping
= MI_DEBUG_MAPPING
;
33 PMMPTE MmDebugPte
= NULL
;
35 /* FUNCTIONS ******************************************************************/
39 MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress
,
44 PVOID MappingBaseAddress
;
46 /* Check if we are called too early */
47 if (MmDebugPte
== NULL
)
49 /* The structures we require aren't initialized yet, fail */
50 KdpDprintf("MiDbgTranslatePhysicalAddress called too early! "
56 /* FIXME: No support for cache flags yet */
57 if ((Flags
& (MMDBG_COPY_CACHED
|
59 MMDBG_COPY_WRITE_COMBINED
)) != 0)
62 KdpDprintf("MiDbgTranslatePhysicalAddress: Cache flags not yet supported. "
64 Flags
& (MMDBG_COPY_CACHED
|
66 MMDBG_COPY_WRITE_COMBINED
));
70 /* Save the base address of our mapping page */
71 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
73 /* Get the template */
74 TempPte
= ValidKernelPte
;
76 /* Convert physical address to PFN */
77 Pfn
= (PFN_NUMBER
)(PhysicalAddress
>> PAGE_SHIFT
);
79 /* Check if this could be an I/O mapping */
80 if (!MiGetPfnEntry(Pfn
))
82 /* FIXME: We don't support this yet */
83 KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. "
90 /* Set the PFN in the PTE */
91 TempPte
.u
.Hard
.PageFrameNumber
= Pfn
;
94 /* Map the PTE and invalidate its TLB entry */
95 *MmDebugPte
= TempPte
;
96 KeInvalidateTlbEntry(MappingBaseAddress
);
98 /* Calculate and return the virtual offset into our mapping page */
99 return (PVOID
)((ULONG_PTR
)MappingBaseAddress
+
100 BYTE_OFFSET(PhysicalAddress
));
105 MiDbgUnTranslatePhysicalAddress(VOID
)
107 PVOID MappingBaseAddress
;
109 /* The address must still be valid at this point */
110 MappingBaseAddress
= MiPteToAddress(MmDebugPte
);
111 ASSERT(MmIsAddressValid(MappingBaseAddress
));
113 /* Clear the mapping PTE and invalidate its TLB entry */
114 MmDebugPte
->u
.Long
= 0;
115 KeInvalidateTlbEntry(MappingBaseAddress
);
120 // We handle 8-byte requests at most
122 C_ASSERT(MMDBG_COPY_MAX_SIZE
== 8);
126 MmDbgCopyMemory(IN ULONG64 Address
,
132 ULONG64 PhysicalAddress
;
134 PVOID CopyDestination
, CopySource
;
136 /* No local kernel debugging support yet, so don't worry about locking */
137 ASSERT(Flags
& MMDBG_COPY_UNSAFE
);
139 /* We only handle 1, 2, 4 and 8 byte requests */
145 /* Invalid size, fail */
146 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n",
148 return STATUS_INVALID_PARAMETER_3
;
151 /* The copy must be aligned */
152 if ((Address
& (Size
- 1)) != 0)
154 /* Not allowing unaligned access */
155 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n",
158 return STATUS_INVALID_PARAMETER_3
;
161 /* Check for physical or virtual copy */
162 if (Flags
& MMDBG_COPY_PHYSICAL
)
164 /* Physical: translate and map it to our mapping space */
165 TargetAddress
= MiDbgTranslatePhysicalAddress(Address
,
168 /* Check if translation failed */
172 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address %I64x\n",
174 return STATUS_UNSUCCESSFUL
;
177 /* The address we received must be valid! */
178 ASSERT(MmIsAddressValid(TargetAddress
));
182 /* Virtual; truncate it to avoid casts later down */
183 TargetAddress
= (PVOID
)(ULONG_PTR
)Address
;
185 /* Make sure address is valid */
186 if (!MmIsAddressValid(TargetAddress
))
189 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid Virtual Address 0x%p\n",
190 Flags
& MMDBG_COPY_WRITE
? "write" : "read",
192 return STATUS_UNSUCCESSFUL
;
195 /* Not handling session space correctly yet */
196 if (MmIsSessionAddress(TargetAddress
))
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
)))
206 /* Not writable, we need to do a physical copy */
207 Flags
|= MMDBG_COPY_PHYSICAL
;
209 /* Calculate the physical address */
210 PhysicalAddress
= PointerPte
->u
.Hard
.PageFrameNumber
<< PAGE_SHIFT
;
211 PhysicalAddress
+= BYTE_OFFSET(Address
);
213 /* Translate the physical address */
214 TargetAddress
= MiDbgTranslatePhysicalAddress(PhysicalAddress
,
217 /* Check if translation failed */
221 KdpDprintf("MmDbgCopyMemory: Failed to translate for write %I64x (%I64x)\n",
224 return STATUS_UNSUCCESSFUL
;
229 /* Check what kind of operation this is */
230 if (Flags
& MMDBG_COPY_WRITE
)
233 CopyDestination
= TargetAddress
;
239 CopyDestination
= Buffer
;
240 CopySource
= TargetAddress
;
249 *(PUCHAR
)CopyDestination
= *(PUCHAR
)CopySource
;
255 *(PUSHORT
)CopyDestination
= *(PUSHORT
)CopySource
;
261 *(PULONG
)CopyDestination
= *(PULONG
)CopySource
;
267 *(PULONGLONG
)CopyDestination
= *(PULONGLONG
)CopySource
;
270 /* Size is sanitized above */
274 /* Get rid of the mapping if this was a physical copy */
275 if (Flags
& MMDBG_COPY_PHYSICAL
)
277 /* Unmap and flush it */
278 MiDbgUnTranslatePhysicalAddress();
281 /* And we are done */
282 return STATUS_SUCCESS
;