ReactOS  0.4.15-dev-1152-g6c94e4f
kdmemsup.c
Go to the documentation of this file.
1 /*****************************************************************************\
2  * *
3  * This file is current kept ONLY for DOCUMENTATION purposes, until *
4  * we are sure that all the functionality (e.g. regarding the "big pages") *
5  * are fully present in Mm and in mm/ARM3/mmdbg.c that supersedes this file. *
6  * *
7 \*****************************************************************************/
8 
9 /*
10  * COPYRIGHT: See COPYING in the top level directory
11  * PROJECT: ReactOS Kernel
12  * FILE: ntoskrnl/kd/i386/kdmemsup.c
13  * PURPOSE: Kernel Debugger Safe Memory Support
14  *
15  * PROGRAMMERS: arty
16  */
17 
18 #include <ntoskrnl.h>
19 #define NDEBUG
20 #include <debug.h>
21 
22 #define HIGH_PHYS_MASK 0x80000000
23 #define PAGE_TABLE_MASK 0x3ff
24 #define BIG_PAGE_SIZE (1<<22)
25 #define CR4_PAGE_SIZE_BIT 0x10
26 #define PDE_PRESENT_BIT 0x01
27 #define PDE_W_BIT 0x02
28 #define PDE_PWT_BIT 0x08
29 #define PDE_PCD_BIT 0x10
30 #define PDE_ACCESSED_BIT 0x20
31 #define PDE_DIRTY_BIT 0x40
32 #define PDE_PS_BIT 0x80
33 
34 #define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE)
35 #define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE)
36 
37 /* VARIABLES ***************************************************************/
38 
40 
41 static
44 {
45  MMPTE TempPte;
46  PMMPTE PointerPte;
47  ULONG_PTR VirtAddr;
48 
51 
52  if ((PhysAddr & (PAGE_SIZE - 1)) + Len > PAGE_SIZE)
53  {
54  TempPte.u.Hard.PageFrameNumber = (PhysAddr >> PAGE_SHIFT) + 1;
56  *PointerPte = TempPte;
57  VirtAddr = (ULONG_PTR)PointerPte << 10;
58  KeInvalidateTlbEntry((PVOID)VirtAddr);
59  }
60 
61  TempPte.u.Hard.PageFrameNumber = PhysAddr >> PAGE_SHIFT;
63  *PointerPte = TempPte;
64  VirtAddr = (ULONG_PTR)PointerPte << 10;
65  KeInvalidateTlbEntry((PVOID)VirtAddr);
66 
67  return VirtAddr + (PhysAddr & (PAGE_SIZE - 1));
68 }
69 
70 static
73 {
74  ULONG_PTR Addr;
75  ULONGLONG Result = 0;
76 
77  Addr = KdpPhysMap(PhysAddr, Len);
78 
79  switch (Len)
80  {
81  case 8:
82  Result = *((PULONGLONG)Addr);
83  break;
84  case 4:
85  Result = *((PULONG)Addr);
86  break;
87  case 2:
88  Result = *((PUSHORT)Addr);
89  break;
90  case 1:
91  Result = *((PUCHAR)Addr);
92  break;
93  }
94 
95  return Result;
96 }
97 
98 static
99 VOID
101 {
102  ULONG_PTR Addr;
103 
104  Addr = KdpPhysMap(PhysAddr, Len);
105 
106  switch (Len)
107  {
108  case 8:
109  *((PULONGLONG)Addr) = Value;
110  break;
111  case 4:
112  *((PULONG)Addr) = Value;
113  break;
114  case 2:
115  *((PUSHORT)Addr) = Value;
116  break;
117  case 1:
118  *((PUCHAR)Addr) = Value;
119  break;
120  }
121 }
122 
123 static
124 BOOLEAN
126 {
127  ULONG_PTR CR3Value = __readcr3();
128  ULONG_PTR CR4Value = __readcr4();
129  ULONG_PTR PageDirectory = (CR3Value & ~(PAGE_SIZE-1)) +
130  ((Addr >> 22) * sizeof(ULONG));
131  ULONG_PTR PageDirectoryEntry = KdpPhysRead(PageDirectory, sizeof(ULONG));
132 
133  /* Not present -> fail */
134  if (!(PageDirectoryEntry & PDE_PRESENT_BIT))
135  {
136  return FALSE;
137  }
138 
139  /* Big Page? */
140  if ((PageDirectoryEntry & PDE_PS_BIT) && (CR4Value & CR4_PAGE_SIZE_BIT))
141  {
142  *ResultAddr = (PageDirectoryEntry & ~(BIG_PAGE_SIZE-1)) +
143  (Addr & (BIG_PAGE_SIZE-1));
144  return TRUE;
145  }
146  else
147  {
148  ULONG_PTR PageTableAddr =
149  (PageDirectoryEntry & ~(PAGE_SIZE-1)) +
150  ((Addr >> PAGE_SHIFT) & PAGE_TABLE_MASK) * sizeof(ULONG);
151  ULONG_PTR PageTableEntry = KdpPhysRead(PageTableAddr, sizeof(ULONG));
152  if (PageTableEntry & PDE_PRESENT_BIT)
153  {
154  *ResultAddr = (PageTableEntry & ~(PAGE_SIZE-1)) +
155  (Addr & (PAGE_SIZE-1));
156  return TRUE;
157  }
158  }
159 
160  return FALSE;
161 }
162 
163 BOOLEAN
164 NTAPI
166 {
167  ULONG_PTR ResultPhysAddr;
168 
169  if (!KdpPhysAccess)
170  {
171  memcpy(Value, (PVOID)Addr, Len);
172  return TRUE;
173  }
174 
175  memset(Value, 0, Len);
176 
177  if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
178  return FALSE;
179 
180  switch (Len)
181  {
182  case 8:
183  *((PULONGLONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
184  break;
185  case 4:
186  *((PULONG)Value) = KdpPhysRead(ResultPhysAddr, Len);
187  break;
188  case 2:
189  *((PUSHORT)Value) = KdpPhysRead(ResultPhysAddr, Len);
190  break;
191  case 1:
192  *((PUCHAR)Value) = KdpPhysRead(ResultPhysAddr, Len);
193  break;
194  }
195 
196  return TRUE;
197 }
198 
199 BOOLEAN
200 NTAPI
202 {
203  ULONG_PTR ResultPhysAddr;
204 
205  if (!KdpPhysAccess)
206  {
207  memcpy((PVOID)Addr, &Value, Len);
208  return TRUE;
209  }
210 
211  if (!KdpTranslateAddress(Addr, &ResultPhysAddr))
212  return FALSE;
213 
214  KdpPhysWrite(ResultPhysAddr, Len, Value);
215  return TRUE;
216 }
217 
218 VOID
219 NTAPI
221 {
223 }
224 
225 /* EOF */
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
static BOOLEAN KdpPhysAccess
Definition: kdmemsup.c:39
#define TRUE
Definition: types.h:120
static VOID KdpPhysWrite(ULONG_PTR PhysAddr, LONG Len, ULONGLONG Value)
Definition: kdmemsup.c:100
#define PDE_PRESENT_BIT
Definition: kdmemsup.c:26
unsigned char * PUCHAR
Definition: retypes.h:3
VOID NTAPI KdpEnableSafeMem(VOID)
Definition: kdmemsup.c:220
__INTRIN_INLINE unsigned long __readcr3(void)
Definition: intrin_x86.h:1720
IN UCHAR Value
Definition: halp.h:394
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MI_KDBG_TMP_PAGE_0
Definition: kdmemsup.c:35
#define PDE_W_BIT
Definition: kdmemsup.c:27
#define PDE_PWT_BIT
Definition: kdmemsup.c:28
#define MiAddressToPte(x)
Definition: mmx86.c:19
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
BOOLEAN NTAPI KdpSafeReadMemory(ULONG_PTR Addr, LONG Len, PVOID Value)
Definition: kdmemsup.c:165
static ULONG_PTR KdpPhysMap(ULONG_PTR PhysAddr, LONG Len)
Definition: kdmemsup.c:43
static BOOLEAN KdpTranslateAddress(ULONG_PTR Addr, PULONG_PTR ResultAddr)
Definition: kdmemsup.c:125
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:201
#define PDE_DIRTY_BIT
Definition: kdmemsup.c:31
uint64_t ULONGLONG
Definition: typedefs.h:67
#define Len
Definition: deflate.h:82
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
BOOLEAN NTAPI KdpSafeWriteMemory(ULONG_PTR Addr, LONG Len, ULONGLONG Value)
Definition: kdmemsup.c:201
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_SIZE
Definition: env_spec_w32.h:49
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1727
#define PDE_PS_BIT
Definition: kdmemsup.c:32
#define BIG_PAGE_SIZE
Definition: kdmemsup.c:24
unsigned int * PULONG
Definition: retypes.h:1
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:384
#define CR4_PAGE_SIZE_BIT
Definition: kdmemsup.c:25
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define PAGE_TABLE_MASK
Definition: kdmemsup.c:23
#define PDE_PCD_BIT
Definition: kdmemsup.c:29
static ULONGLONG KdpPhysRead(ULONG_PTR PhysAddr, LONG Len)
Definition: kdmemsup.c:72
#define memset(x, y, z)
Definition: compat.h:39
unsigned short * PUSHORT
Definition: retypes.h:2
#define PDE_ACCESSED_BIT
Definition: kdmemsup.c:30
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define MI_KDBG_TMP_PAGE_1
Definition: kdmemsup.c:34