2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel
4 * FILE: ntoskrnl/kd/i386/kdmemsup.c
5 * PURPOSE: Kernel Debugger Safe Memory Support
14 #define HIGH_PHYS_MASK 0x80000000
15 #define PAGE_TABLE_MASK 0x3ff
16 #define BIG_PAGE_SIZE (1<<22)
17 #define CR4_PAGE_SIZE_BIT 0x10
18 #define PDE_PRESENT_BIT 0x01
19 #define PDE_W_BIT 0x02
20 #define PDE_PWT_BIT 0x08
21 #define PDE_PCD_BIT 0x10
22 #define PDE_ACCESSED_BIT 0x20
23 #define PDE_DIRTY_BIT 0x40
24 #define PDE_PS_BIT 0x80
26 #define MI_KDBG_TMP_PAGE_1 (HYPER_SPACE + 0x400000 - PAGE_SIZE)
27 #define MI_KDBG_TMP_PAGE_0 (MI_KDBG_TMP_PAGE_1 - PAGE_SIZE)
29 /* VARIABLES ***************************************************************/
31 static BOOLEAN KdpPhysAccess
= FALSE
;
35 KdpPhysMap(ULONG_PTR PhysAddr
, LONG Len
)
41 TempPte
.u
.Long
= PDE_PRESENT_BIT
| PDE_W_BIT
| PDE_PWT_BIT
|
42 PDE_PCD_BIT
| PDE_ACCESSED_BIT
| PDE_DIRTY_BIT
;
44 if ((PhysAddr
& (PAGE_SIZE
- 1)) + Len
> PAGE_SIZE
)
46 TempPte
.u
.Hard
.PageFrameNumber
= (PhysAddr
>> PAGE_SHIFT
) + 1;
47 PointerPte
= MiAddressToPte(MI_KDBG_TMP_PAGE_1
);
48 *PointerPte
= TempPte
;
49 VirtAddr
= (ULONG_PTR
)PointerPte
<< 10;
50 KeInvalidateTlbEntry((PVOID
)VirtAddr
);
53 TempPte
.u
.Hard
.PageFrameNumber
= PhysAddr
>> PAGE_SHIFT
;
54 PointerPte
= MiAddressToPte(MI_KDBG_TMP_PAGE_0
);
55 *PointerPte
= TempPte
;
56 VirtAddr
= (ULONG_PTR
)PointerPte
<< 10;
57 KeInvalidateTlbEntry((PVOID
)VirtAddr
);
59 return VirtAddr
+ (PhysAddr
& (PAGE_SIZE
- 1));
64 KdpPhysRead(ULONG_PTR PhysAddr
, LONG Len
)
69 Addr
= KdpPhysMap(PhysAddr
, Len
);
74 Result
= *((PULONGLONG
)Addr
);
77 Result
= *((PULONG
)Addr
);
80 Result
= *((PUSHORT
)Addr
);
83 Result
= *((PUCHAR
)Addr
);
92 KdpPhysWrite(ULONG_PTR PhysAddr
, LONG Len
, ULONGLONG Value
)
96 Addr
= KdpPhysMap(PhysAddr
, Len
);
101 *((PULONGLONG
)Addr
) = Value
;
104 *((PULONG
)Addr
) = Value
;
107 *((PUSHORT
)Addr
) = Value
;
110 *((PUCHAR
)Addr
) = Value
;
117 KdpTranslateAddress(ULONG_PTR Addr
, PULONG_PTR ResultAddr
)
119 ULONG_PTR CR3Value
= __readcr3();
120 ULONG_PTR CR4Value
= __readcr4();
121 ULONG_PTR PageDirectory
= (CR3Value
& ~(PAGE_SIZE
-1)) +
122 ((Addr
>> 22) * sizeof(ULONG
));
123 ULONG_PTR PageDirectoryEntry
= KdpPhysRead(PageDirectory
, sizeof(ULONG
));
125 /* Not present -> fail */
126 if (!(PageDirectoryEntry
& PDE_PRESENT_BIT
))
132 if ((PageDirectoryEntry
& PDE_PS_BIT
) && (CR4Value
& CR4_PAGE_SIZE_BIT
))
134 *ResultAddr
= (PageDirectoryEntry
& ~(BIG_PAGE_SIZE
-1)) +
135 (Addr
& (BIG_PAGE_SIZE
-1));
140 ULONG_PTR PageTableAddr
=
141 (PageDirectoryEntry
& ~(PAGE_SIZE
-1)) +
142 ((Addr
>> PAGE_SHIFT
) & PAGE_TABLE_MASK
) * sizeof(ULONG
);
143 ULONG_PTR PageTableEntry
= KdpPhysRead(PageTableAddr
, sizeof(ULONG
));
144 if (PageTableEntry
& PDE_PRESENT_BIT
)
146 *ResultAddr
= (PageTableEntry
& ~(PAGE_SIZE
-1)) +
147 (Addr
& (PAGE_SIZE
-1));
157 KdpSafeReadMemory(ULONG_PTR Addr
, LONG Len
, PVOID Value
)
159 ULONG_PTR ResultPhysAddr
;
163 memcpy(Value
, (PVOID
)Addr
, Len
);
167 memset(Value
, 0, Len
);
169 if (!KdpTranslateAddress(Addr
, &ResultPhysAddr
))
175 *((PULONGLONG
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
178 *((PULONG
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
181 *((PUSHORT
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
184 *((PUCHAR
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
193 KdpSafeWriteMemory(ULONG_PTR Addr
, LONG Len
, ULONGLONG Value
)
195 ULONG_PTR ResultPhysAddr
;
199 memcpy((PVOID
)Addr
, &Value
, Len
);
203 if (!KdpTranslateAddress(Addr
, &ResultPhysAddr
))
206 KdpPhysWrite(ResultPhysAddr
, Len
, Value
);
212 KdpEnableSafeMem(VOID
)
214 KdpPhysAccess
= TRUE
;