Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmdbg.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: ntoskrnl/mm/ARM3/mmdbg.c 00005 * PURPOSE: Memory Manager support routines for the Kernel Debugger 00006 * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 #define MODULE_INVOLVED_IN_ARM3 00016 #include "../ARM3/miarm.h" 00017 00018 #ifndef _WINKD_ 00019 #define KdpDprintf DPRINT 00020 #elif defined(NDEBUG) 00021 #define KdpDprintf(...) 00022 #endif 00023 00024 /* GLOBALS ********************************************************************/ 00025 00026 PVOID MiDebugMapping = MI_DEBUG_MAPPING; 00027 PMMPTE MmDebugPte = NULL; 00028 00029 /* FUNCTIONS ******************************************************************/ 00030 00031 BOOLEAN 00032 NTAPI 00033 MmIsSessionAddress(IN PVOID Address) 00034 { 00035 // 00036 // No session space support yet 00037 // 00038 return FALSE; 00039 } 00040 00041 PVOID 00042 NTAPI 00043 MiDbgTranslatePhysicalAddress(IN ULONG64 PhysicalAddress, 00044 IN ULONG Flags) 00045 { 00046 PFN_NUMBER Pfn; 00047 MMPTE TempPte; 00048 PVOID MappingBaseAddress; 00049 00050 // 00051 // Check if we are called too early 00052 // 00053 if (MmDebugPte == NULL) 00054 { 00055 // 00056 // The structures we require aren't initialized yet, fail 00057 // 00058 KdpDprintf("MiDbgTranslatePhysicalAddress called too early! " 00059 "Address: 0x%I64x\n", PhysicalAddress); 00060 return NULL; 00061 } 00062 00063 // 00064 // FIXME: No support for cache flags yet 00065 // 00066 if ((Flags & (MMDBG_COPY_CACHED | 00067 MMDBG_COPY_UNCACHED | 00068 MMDBG_COPY_WRITE_COMBINED)) != 0) 00069 { 00070 // 00071 // Fail 00072 // 00073 KdpDprintf("MiDbgTranslatePhysicalAddress: Cache Flags not yet supported. " 00074 "Flags: 0x%lx\n", Flags & (MMDBG_COPY_CACHED | 00075 MMDBG_COPY_UNCACHED | 00076 MMDBG_COPY_WRITE_COMBINED)); 00077 return NULL; 00078 } 00079 00080 // 00081 // Save the base address of our mapping page 00082 // 00083 MappingBaseAddress = MiPteToAddress(MmDebugPte); 00084 00085 // 00086 // Get the template 00087 // 00088 TempPte = ValidKernelPte; 00089 00090 // 00091 // Convert physical address to PFN 00092 // 00093 Pfn = (PFN_NUMBER)(PhysicalAddress >> PAGE_SHIFT); 00094 00095 /* Check if this could be an I/O mapping */ 00096 if (!MiGetPfnEntry(Pfn)) 00097 { 00098 // 00099 // FIXME: We don't support this yet 00100 // 00101 KdpDprintf("MiDbgTranslatePhysicalAddress: I/O Space not yet supported. " 00102 "PFN: 0x%I64x\n", (ULONG64)Pfn); 00103 return NULL; 00104 } 00105 else 00106 { 00107 // 00108 // Set the PFN in the PTE 00109 // 00110 TempPte.u.Hard.PageFrameNumber = Pfn; 00111 } 00112 00113 // 00114 // Map the PTE and invalidate its TLB entry 00115 // 00116 *MmDebugPte = TempPte; 00117 KeInvalidateTlbEntry(MappingBaseAddress); 00118 00119 // 00120 // Calculate and return the virtual offset into our mapping page 00121 // 00122 return (PVOID)((ULONG_PTR)MappingBaseAddress + 00123 BYTE_OFFSET(PhysicalAddress)); 00124 } 00125 00126 VOID 00127 NTAPI 00128 MiDbgUnTranslatePhysicalAddress(VOID) 00129 { 00130 PVOID MappingBaseAddress = MiPteToAddress(MmDebugPte); 00131 00132 // 00133 // The address must still be valid at this point 00134 // 00135 ASSERT(MmIsAddressValid(MappingBaseAddress)); 00136 00137 // 00138 // Clear the mapping PTE and invalidate its TLB entry 00139 // 00140 MmDebugPte->u.Long = 0; 00141 KeInvalidateTlbEntry(MappingBaseAddress); 00142 } 00143 00144 NTSTATUS 00145 NTAPI 00146 MmDbgCopyMemory(IN ULONG64 Address, 00147 IN PVOID Buffer, 00148 IN ULONG Size, 00149 IN ULONG Flags) 00150 { 00151 NTSTATUS Status; 00152 PVOID TargetAddress; 00153 ULONG64 PhysicalAddress; 00154 PMMPTE PointerPte; 00155 00156 // 00157 // No local kernel debugging support yet, so don't worry about locking 00158 // 00159 ASSERT(Flags & MMDBG_COPY_UNSAFE); 00160 00161 // 00162 // We only handle 1, 2, 4 and 8 byte requests 00163 // 00164 if ((Size != 1) && 00165 (Size != 2) && 00166 (Size != 4) && 00167 (Size != MMDBG_COPY_MAX_SIZE)) 00168 { 00169 // 00170 // Invalid size, fail 00171 // 00172 KdpDprintf("MmDbgCopyMemory: Received Illegal Size 0x%lx\n", Size); 00173 return STATUS_INVALID_PARAMETER_3; 00174 } 00175 00176 // 00177 // The copy must be aligned 00178 // 00179 if ((Address & (Size - 1)) != 0) 00180 { 00181 // 00182 // Fail 00183 // 00184 KdpDprintf("MmDbgCopyMemory: Received Unaligned Address 0x%I64x Size %lx\n", 00185 Address, Size); 00186 return STATUS_INVALID_PARAMETER_3; 00187 } 00188 00189 // 00190 // Check if this is physical or virtual copy 00191 // 00192 if (Flags & MMDBG_COPY_PHYSICAL) 00193 { 00194 // 00195 // Physical: translate and map it to our mapping space 00196 // 00197 TargetAddress = MiDbgTranslatePhysicalAddress(Address, Flags); 00198 00199 // 00200 // Check if translation failed 00201 // 00202 if (!TargetAddress) 00203 { 00204 // 00205 // Fail 00206 // 00207 KdpDprintf("MmDbgCopyMemory: Failed to Translate Physical Address " 00208 "%I64x\n", Address); 00209 return STATUS_UNSUCCESSFUL; 00210 } 00211 00212 // 00213 // The address we received must be valid! 00214 // 00215 ASSERT(MmIsAddressValid(TargetAddress)); 00216 } 00217 else 00218 { 00219 // 00220 // Virtual; truncate it to avoid casts later down 00221 // 00222 TargetAddress = (PVOID)(ULONG_PTR)Address; 00223 00224 // 00225 // Check if the address is invalid 00226 // 00227 if (!MmIsAddressValid(TargetAddress)) 00228 { 00229 // 00230 // Fail 00231 // 00232 KdpDprintf("MmDbgCopyMemory: Failing %s for invalid " 00233 "Virtual Address 0x%p\n", 00234 Flags & MMDBG_COPY_WRITE ? "write" : "read", 00235 TargetAddress); 00236 return STATUS_UNSUCCESSFUL; 00237 } 00238 00239 // 00240 // No session space support yet 00241 // 00242 ASSERT(MmIsSessionAddress(TargetAddress) == FALSE); 00243 00244 /* If we are going to write to the address, then check if its writable */ 00245 PointerPte = MiAddressToPte(TargetAddress); 00246 if ((Flags & MMDBG_COPY_WRITE) && !MI_IS_PAGE_WRITEABLE(PointerPte)) 00247 { 00248 /* Not writable, we need to do a physical copy */ 00249 Flags |= MMDBG_COPY_PHYSICAL; 00250 00251 /* Calculate the physical address */ 00252 PhysicalAddress = PointerPte->u.Hard.PageFrameNumber << PAGE_SHIFT; 00253 PhysicalAddress += BYTE_OFFSET(Address); 00254 00255 /* Translate the physical address */ 00256 TargetAddress = MiDbgTranslatePhysicalAddress(PhysicalAddress, Flags); 00257 00258 /* Check if translation failed */ 00259 if (!TargetAddress) 00260 { 00261 /* Fail */ 00262 KdpDprintf("MmDbgCopyMemory: Failed to translate for write " 00263 "%I64x (%I64x)\n", PhysicalAddress, Address); 00264 return STATUS_UNSUCCESSFUL; 00265 } 00266 } 00267 } 00268 00269 // 00270 // Use SEH to try to catch anything else somewhat cleanly 00271 // 00272 _SEH2_TRY 00273 { 00274 // 00275 // Check if this is read or write 00276 // 00277 if (Flags & MMDBG_COPY_WRITE) 00278 { 00279 // 00280 // Do the write 00281 // 00282 RtlCopyMemory(TargetAddress, 00283 Buffer, 00284 Size); 00285 } 00286 else 00287 { 00288 // 00289 // Do the read 00290 // 00291 RtlCopyMemory(Buffer, 00292 TargetAddress, 00293 Size); 00294 } 00295 00296 // 00297 // Copy succeeded 00298 // 00299 Status = STATUS_SUCCESS; 00300 } 00301 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00302 { 00303 // 00304 // Get the exception code 00305 // 00306 Status = _SEH2_GetExceptionCode(); 00307 } 00308 _SEH2_END; 00309 00310 // 00311 // Get rid of the mapping if this was a physical copy 00312 // 00313 if (Flags & MMDBG_COPY_PHYSICAL) 00314 { 00315 // 00316 // Unmap and flush it 00317 // 00318 MiDbgUnTranslatePhysicalAddress(); 00319 } 00320 00321 // 00322 // Return status to caller 00323 // 00324 return Status; 00325 } Generated on Sat May 26 2012 04:36:22 for ReactOS by
1.7.6.1
|