1 /*****************************************************************************\
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. *
7 \*****************************************************************************/
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
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
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)
37 /* VARIABLES ***************************************************************/
39 static BOOLEAN KdpPhysAccess
= FALSE
;
43 KdpPhysMap(ULONG_PTR PhysAddr
, LONG Len
)
49 TempPte
.u
.Long
= PDE_PRESENT_BIT
| PDE_W_BIT
| PDE_PWT_BIT
|
50 PDE_PCD_BIT
| PDE_ACCESSED_BIT
| PDE_DIRTY_BIT
;
52 if ((PhysAddr
& (PAGE_SIZE
- 1)) + Len
> PAGE_SIZE
)
54 TempPte
.u
.Hard
.PageFrameNumber
= (PhysAddr
>> PAGE_SHIFT
) + 1;
55 PointerPte
= MiAddressToPte((PVOID
)MI_KDBG_TMP_PAGE_1
);
56 *PointerPte
= TempPte
;
57 VirtAddr
= (ULONG_PTR
)PointerPte
<< 10;
58 KeInvalidateTlbEntry((PVOID
)VirtAddr
);
61 TempPte
.u
.Hard
.PageFrameNumber
= PhysAddr
>> PAGE_SHIFT
;
62 PointerPte
= MiAddressToPte((PVOID
)MI_KDBG_TMP_PAGE_0
);
63 *PointerPte
= TempPte
;
64 VirtAddr
= (ULONG_PTR
)PointerPte
<< 10;
65 KeInvalidateTlbEntry((PVOID
)VirtAddr
);
67 return VirtAddr
+ (PhysAddr
& (PAGE_SIZE
- 1));
72 KdpPhysRead(ULONG_PTR PhysAddr
, LONG Len
)
77 Addr
= KdpPhysMap(PhysAddr
, Len
);
82 Result
= *((PULONGLONG
)Addr
);
85 Result
= *((PULONG
)Addr
);
88 Result
= *((PUSHORT
)Addr
);
91 Result
= *((PUCHAR
)Addr
);
100 KdpPhysWrite(ULONG_PTR PhysAddr
, LONG Len
, ULONGLONG Value
)
104 Addr
= KdpPhysMap(PhysAddr
, Len
);
109 *((PULONGLONG
)Addr
) = Value
;
112 *((PULONG
)Addr
) = Value
;
115 *((PUSHORT
)Addr
) = Value
;
118 *((PUCHAR
)Addr
) = Value
;
125 KdpTranslateAddress(ULONG_PTR Addr
, PULONG_PTR ResultAddr
)
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
));
133 /* Not present -> fail */
134 if (!(PageDirectoryEntry
& PDE_PRESENT_BIT
))
140 if ((PageDirectoryEntry
& PDE_PS_BIT
) && (CR4Value
& CR4_PAGE_SIZE_BIT
))
142 *ResultAddr
= (PageDirectoryEntry
& ~(BIG_PAGE_SIZE
-1)) +
143 (Addr
& (BIG_PAGE_SIZE
-1));
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
)
154 *ResultAddr
= (PageTableEntry
& ~(PAGE_SIZE
-1)) +
155 (Addr
& (PAGE_SIZE
-1));
165 KdpSafeReadMemory(ULONG_PTR Addr
, LONG Len
, PVOID Value
)
167 ULONG_PTR ResultPhysAddr
;
171 memcpy(Value
, (PVOID
)Addr
, Len
);
175 memset(Value
, 0, Len
);
177 if (!KdpTranslateAddress(Addr
, &ResultPhysAddr
))
183 *((PULONGLONG
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
186 *((PULONG
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
189 *((PUSHORT
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
192 *((PUCHAR
)Value
) = KdpPhysRead(ResultPhysAddr
, Len
);
201 KdpSafeWriteMemory(ULONG_PTR Addr
, LONG Len
, ULONGLONG Value
)
203 ULONG_PTR ResultPhysAddr
;
207 memcpy((PVOID
)Addr
, &Value
, Len
);
211 if (!KdpTranslateAddress(Addr
, &ResultPhysAddr
))
214 KdpPhysWrite(ResultPhysAddr
, Len
, Value
);
220 KdpEnableSafeMem(VOID
)
222 KdpPhysAccess
= TRUE
;