ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mmdbg.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.