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

kdmemsup.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Kernel
00004  * FILE:            ntoskrnl/kd/i386/kdmemsup.c
00005  * PURPOSE:         Kernel Debugger Safe Memory Support
00006  *
00007  * PROGRAMMERS:     arty
00008  */
00009 
00010 #include <ntoskrnl.h>
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 #define HIGH_PHYS_MASK 0x80000000
00015 #define PAGE_TABLE_MASK 0x3ff
00016 #define BIG_PAGE_SIZE (1<<22)
00017 #define CR4_PAGE_SIZE_BIT 0x10
00018 #define PDE_PRESENT_BIT 0x01
00019 #define PDE_W_BIT 0x02
00020 #define PDE_PWT_BIT 0x08
00021 #define PDE_PCD_BIT 0x10
00022 #define PDE_ACCESSED_BIT 0x20
00023 #define PDE_DIRTY_BIT 0x40
00024 #define PDE_PS_BIT 0x80
00025 
00026 #define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE)
00027 #define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE)
00028 
00029 /* VARIABLES ***************************************************************/
00030 
00031 static BOOLEAN KdpPhysAccess = FALSE;
00032 
00033 static
00034 ULONG_PTR
00035 KdpPhysMap(ULONG_PTR PhysAddr, LONG Len)
00036 {
00037     MMPTE TempPte;
00038     PMMPTE PointerPte;
00039     ULONG_PTR VirtAddr;
00040 
00041     TempPte.u.Long = PDE_PRESENT_BIT | PDE_W_BIT | PDE_PWT_BIT |
00042                      PDE_PCD_BIT | PDE_ACCESSED_BIT | PDE_DIRTY_BIT;
00043 
00044     if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE)
00045     {
00046         TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1;
00047         PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_1);
00048         *PointerPte = TempPte;
00049         VirtAddr = (ULONG_PTR)PointerPte << 10;
00050         KeInvalidateTlbEntry((PVOID)VirtAddr);
00051     }
00052 
00053     TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT;
00054     PointerPte = MiAddressToPte(MI_KDBG_TMP_PAGE_0);
00055     *PointerPte = TempPte;
00056     VirtAddr = (ULONG_PTR)PointerPte << 10;
00057     KeInvalidateTlbEntry((PVOID)VirtAddr);
00058 
00059     return VirtAddr + (PhysAddr & (PAGE_SIZE - 1));
00060 }
00061 
00062 static
00063 ULONGLONG
00064 KdpPhysRead(ULONG_PTR PhysAddr, LONG Len)
00065 {
00066     ULONG_PTR Addr;
00067     ULONGLONG Result = 0;
00068 
00069     Addr = KdpPhysMap(PhysAddr, Len);
00070 
00071     switch (Len)
00072     {
00073     case 8:
00074         Result = *((PULONGLONG)Addr);
00075         break;
00076     case 4:
00077         Result = *((PULONG)Addr);
00078         break;
00079     case 2:
00080         Result = *((PUSHORT)Addr);
00081         break;
00082     case 1:
00083         Result = *((PUCHAR)Addr);
00084         break;
00085     }
00086 
00087     return Result;
00088 }
00089 
00090 static
00091 VOID
00092 KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value)
00093 {
00094     ULONG_PTR Addr;
00095 
00096     Addr = KdpPhysMap(PhysAddr, Len);
00097 
00098     switch (Len)
00099     {
00100     case 8:
00101         *((PULONGLONG)Addr) = Value;
00102         break;
00103     case 4:
00104         *((PULONG)Addr) = Value;
00105         break;
00106     case 2:
00107         *((PUSHORT)Addr) = Value;
00108         break;
00109     case 1:
00110         *((PUCHAR)Addr) = Value;
00111         break;
00112     }
00113 }
00114 
00115 BOOLEAN
00116 NTAPI
00117 KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr)
00118 {
00119     ULONG_PTR CR3Value = __readcr3();
00120     ULONG_PTR CR4Value = __readcr4();
00121     ULONG_PTR PageDirectory = (CR3Value & ~(PAGE_SIZE-1)) + 
00122         ((Addr >> 22) * sizeof(ULONG));
00123     ULONG_PTR PageDirectoryEntry = KdpPhysRead(PageDirectory, sizeof(ULONG));
00124 
00125     /* Not present -> fail */
00126     if (!(PageDirectoryEntry & PDE_PRESENT_BIT))
00127     {
00128         return FALSE;
00129     }
00130 
00131     /* Big Page? */
00132     if ((PageDirectoryEntry & PDE_PS_BIT) && (CR4Value & CR4_PAGE_SIZE_BIT))
00133     {
00134         *ResultAddr = (PageDirectoryEntry & ~(BIG_PAGE_SIZE-1)) +
00135             (Addr & (BIG_PAGE_SIZE-1));
00136         return TRUE;
00137     }
00138     else
00139     {
00140         ULONG_PTR PageTableAddr = 
00141             (PageDirectoryEntry & ~(PAGE_SIZE-1)) +
00142             ((Addr >> PAGE_SHIFT) & PAGE_TABLE_MASK) * sizeof(ULONG);
00143         ULONG_PTR PageTableEntry = KdpPhysRead(PageTableAddr, sizeof(ULONG));
00144         if (PageTableEntry & PDE_PRESENT_BIT)
00145         {
00146             *ResultAddr = (PageTableEntry & ~(PAGE_SIZE-1)) +
00147                 (Addr & (PAGE_SIZE-1));
00148             return TRUE;
00149         }
00150     }
00151 
00152     return FALSE;
00153 }
00154 
00155 BOOLEAN
00156 NTAPI
00157 KdpSafeReadMemory(ULONG_PTR Addr, LONG Len, PVOID Value)
00158 {
00159     ULONG_PTR ResultPhysAddr;
00160 
00161     if (!KdpPhysAccess)
00162     {
00163         memcpy(Value, (PVOID)Addr, Len);
00164         return TRUE;
00165     }
00166 
00167     memset(Value, 0, Len);
00168             
00169     if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
00170         return FALSE;
00171 
00172     switch (Len)
00173     {
00174     case 8:
00175         *((PULONGLONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
00176         break;
00177     case 4:
00178         *((PULONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
00179         break;
00180     case 2:
00181         *((PUSHORT)Value) = KdpPhysRead(ResultPhysAddr, Len);
00182         break;
00183     case 1:
00184         *((PUCHAR)Value) = KdpPhysRead(ResultPhysAddr, Len);
00185         break;
00186     }
00187 
00188     return TRUE;
00189 }
00190 
00191 BOOLEAN
00192 NTAPI
00193 KdpSafeWriteMemory(ULONG_PTR Addr, LONG Len, ULONGLONG Value)
00194 {
00195     ULONG_PTR ResultPhysAddr;
00196 
00197     if (!KdpPhysAccess)
00198     {
00199         memcpy((PVOID)Addr, &Value, Len);
00200         return TRUE;
00201     }
00202             
00203     if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
00204         return FALSE;
00205 
00206     KdpPhysWrite(ResultPhysAddr, Len, Value);
00207     return TRUE;
00208 }
00209 
00210 VOID
00211 NTAPI
00212 KdpEnableSafeMem(VOID)
00213 {
00214     KdpPhysAccess = TRUE;
00215 }
00216 
00217 /* EOF */

Generated on Sun May 27 2012 04:37:19 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.