Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkdmemsup.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
1.7.6.1
|