Sync with trunk r63270.
[reactos.git] / ntoskrnl / kd64 / amd64 / kdx64.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/amd64/kdx64.c
5 * PURPOSE: KD support routines for AMD64
6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #undef UNIMPLEMENTED
16 #define UNIMPLEMENTED KdpDprintf("%s is unimplemented\n", __FUNCTION__)
17
18 /* FUNCTIONS *****************************************************************/
19
20 VOID
21 NTAPI
22 KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,
23 IN PCONTEXT Context)
24 {
25 PKPRCB Prcb;
26 ULONG i;
27
28 /* Check for success */
29 if (NT_SUCCESS(State->u.Continue2.ContinueStatus))
30 {
31 /* Check if we're tracing */
32 if (State->u.Continue2.ControlSet.TraceFlag)
33 {
34 /* Enable TF */
35 Context->EFlags |= EFLAGS_TF;
36 }
37 else
38 {
39 /* Remove it */
40 Context->EFlags &= ~EFLAGS_TF;
41 }
42
43 /* Loop all processors */
44 for (i = 0; i < KeNumberProcessors; i++)
45 {
46 /* Get the PRCB and update DR7 and DR6 */
47 Prcb = KiProcessorBlock[i];
48 Prcb->ProcessorState.SpecialRegisters.KernelDr7 =
49 State->u.Continue2.ControlSet.Dr7;
50 Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0;
51 }
52
53 /* Check if we have new symbol information */
54 if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1)
55 {
56 /* Update it */
57 KdpCurrentSymbolStart =
58 State->u.Continue2.ControlSet.CurrentSymbolStart;
59 KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd;
60 }
61 }
62 }
63
64 VOID
65 NTAPI
66 KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
67 IN PCONTEXT Context)
68 {
69 PKPRCB Prcb = KeGetCurrentPrcb();
70
71 /* Copy i386 specific debug registers */
72 WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.
73 KernelDr6;
74 WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.
75 KernelDr7;
76
77 /* Copy i386 specific segments */
78 WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;
79 WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;
80 WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;
81 WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;
82
83 /* Copy EFlags */
84 WaitStateChange->ControlReport.EFlags = Context->EFlags;
85
86 /* Set Report Flags */
87 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
88 if (WaitStateChange->ControlReport.SegCs == KGDT64_R0_CODE)
89 {
90 WaitStateChange->ControlReport.ReportFlags |= REPORT_STANDARD_CS;
91 }
92 }
93
94 NTSTATUS
95 NTAPI
96 KdpSysReadMsr(IN ULONG Msr,
97 OUT PLARGE_INTEGER MsrValue)
98 {
99 /* Use SEH to protect from invalid MSRs */
100 _SEH2_TRY
101 {
102 MsrValue->QuadPart = __readmsr(Msr);
103 }
104 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
105 {
106 _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
107 }
108 _SEH2_END
109
110 return STATUS_SUCCESS;
111 }
112
113 NTSTATUS
114 NTAPI
115 KdpSysWriteMsr(IN ULONG Msr,
116 IN PLARGE_INTEGER MsrValue)
117 {
118 /* Use SEH to protect from invalid MSRs */
119 _SEH2_TRY
120 {
121 __writemsr(Msr, MsrValue->QuadPart);
122 }
123 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
124 {
125 _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
126 }
127 _SEH2_END
128
129 return STATUS_SUCCESS;
130 }
131
132 NTSTATUS
133 NTAPI
134 KdpSysReadBusData(IN ULONG BusDataType,
135 IN ULONG BusNumber,
136 IN ULONG SlotNumber,
137 IN ULONG Offset,
138 IN PVOID Buffer,
139 IN ULONG Length,
140 OUT PULONG ActualLength)
141 {
142 UNIMPLEMENTED_DBGBREAK();
143 return STATUS_UNSUCCESSFUL;
144 }
145
146 NTSTATUS
147 NTAPI
148 KdpSysWriteBusData(IN ULONG BusDataType,
149 IN ULONG BusNumber,
150 IN ULONG SlotNumber,
151 IN ULONG Offset,
152 IN PVOID Buffer,
153 IN ULONG Length,
154 OUT PULONG ActualLength)
155 {
156 UNIMPLEMENTED_DBGBREAK();
157 return STATUS_UNSUCCESSFUL;
158 }
159
160 NTSTATUS
161 NTAPI
162 KdpSysReadControlSpace(IN ULONG Processor,
163 IN ULONG64 BaseAddress,
164 IN PVOID Buffer,
165 IN ULONG Length,
166 OUT PULONG ActualLength)
167 {
168 PVOID ControlStart;
169 PKPRCB Prcb = KiProcessorBlock[Processor];
170 PKIPCR Pcr = CONTAINING_RECORD(Prcb, KIPCR, Prcb);
171
172 switch (BaseAddress)
173 {
174 case AMD64_DEBUG_CONTROL_SPACE_KPCR:
175 /* Copy a pointer to the Pcr */
176 ControlStart = &Pcr;
177 *ActualLength = sizeof(PVOID);
178 break;
179
180 case AMD64_DEBUG_CONTROL_SPACE_KPRCB:
181 /* Copy a pointer to the Prcb */
182 ControlStart = &Prcb;
183 *ActualLength = sizeof(PVOID);
184 break;
185
186 case AMD64_DEBUG_CONTROL_SPACE_KSPECIAL:
187 /* Copy SpecialRegisters */
188 ControlStart = &Prcb->ProcessorState.SpecialRegisters;
189 *ActualLength = sizeof(KSPECIAL_REGISTERS);
190 break;
191
192 case AMD64_DEBUG_CONTROL_SPACE_KTHREAD:
193 /* Copy a pointer to the current Thread */
194 ControlStart = &Prcb->CurrentThread;
195 *ActualLength = sizeof(PVOID);
196 break;
197
198 default:
199 *ActualLength = 0;
200 ASSERT(FALSE);
201 return STATUS_UNSUCCESSFUL;
202 }
203
204 /* Copy the memory */
205 RtlCopyMemory(Buffer, ControlStart, min(Length, *ActualLength));
206
207 /* Finish up */
208 return STATUS_SUCCESS;
209 }
210
211 NTSTATUS
212 NTAPI
213 KdpSysWriteControlSpace(IN ULONG Processor,
214 IN ULONG64 BaseAddress,
215 IN PVOID Buffer,
216 IN ULONG Length,
217 OUT PULONG ActualLength)
218 {
219 PVOID ControlStart;
220 PKPRCB Prcb = KiProcessorBlock[Processor];
221
222 switch (BaseAddress)
223 {
224 case AMD64_DEBUG_CONTROL_SPACE_KSPECIAL:
225 /* Copy SpecialRegisters */
226 ControlStart = &Prcb->ProcessorState.SpecialRegisters;
227 *ActualLength = sizeof(KSPECIAL_REGISTERS);
228 break;
229
230 default:
231 *ActualLength = 0;
232 ASSERT(FALSE);
233 return STATUS_UNSUCCESSFUL;
234 }
235
236 /* Copy the memory */
237 RtlCopyMemory(ControlStart, Buffer, min(Length, *ActualLength));
238
239 return STATUS_SUCCESS;
240 }
241
242 NTSTATUS
243 NTAPI
244 KdpSysReadIoSpace(IN ULONG InterfaceType,
245 IN ULONG BusNumber,
246 IN ULONG AddressSpace,
247 IN ULONG64 IoAddress,
248 OUT PVOID DataValue,
249 IN ULONG DataSize,
250 OUT PULONG ActualDataSize)
251 {
252 /* Verify parameters */
253 if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)
254 {
255 /* No data was read */
256 *ActualDataSize = 0;
257 return STATUS_INVALID_PARAMETER;
258 }
259
260 /* Check for correct alignment */
261 if ((IoAddress & (DataSize - 1)))
262 {
263 /* Invalid alignment */
264 *ActualDataSize = 0;
265 return STATUS_DATATYPE_MISALIGNMENT;
266 }
267
268 switch (DataSize)
269 {
270 case sizeof(UCHAR):
271 /* Read one UCHAR */
272 *(PUCHAR)DataValue = READ_PORT_UCHAR((PUCHAR)IoAddress);
273 break;
274
275 case sizeof(USHORT):
276 /* Read one USHORT */
277 *(PUSHORT)DataValue = READ_PORT_USHORT((PUSHORT)IoAddress);
278 break;
279
280 case sizeof(ULONG):
281 /* Read one ULONG */
282 *(PULONG)DataValue = READ_PORT_ULONG((PULONG)IoAddress);
283 break;
284
285 default:
286 /* Invalid data size */
287 *ActualDataSize = 0;
288 return STATUS_INVALID_PARAMETER;
289 }
290
291 /* Return the size of the data */
292 *ActualDataSize = DataSize;
293
294 /* Success! */
295 return STATUS_SUCCESS;
296 }
297
298 NTSTATUS
299 NTAPI
300 KdpSysWriteIoSpace(IN ULONG InterfaceType,
301 IN ULONG BusNumber,
302 IN ULONG AddressSpace,
303 IN ULONG64 IoAddress,
304 IN PVOID DataValue,
305 IN ULONG DataSize,
306 OUT PULONG ActualDataSize)
307 {
308 /* Verify parameters */
309 if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)
310 {
311 /* No data was written */
312 *ActualDataSize = 0;
313 return STATUS_INVALID_PARAMETER;
314 }
315
316 /* Check for correct alignment */
317 if ((IoAddress & (DataSize - 1)))
318 {
319 /* Invalid alignment */
320 *ActualDataSize = 0;
321 return STATUS_DATATYPE_MISALIGNMENT;
322 }
323
324 switch (DataSize)
325 {
326 case sizeof(UCHAR):
327 /* Write one UCHAR */
328 WRITE_PORT_UCHAR((PUCHAR)IoAddress, *(PUCHAR)DataValue);
329 break;
330
331 case sizeof(USHORT):
332 /* Write one USHORT */
333 WRITE_PORT_USHORT((PUSHORT)IoAddress, *(PUSHORT)DataValue);
334 break;
335
336 case sizeof(ULONG):
337 /* Write one ULONG */
338 WRITE_PORT_ULONG((PULONG)IoAddress, *(PULONG)DataValue);
339 break;
340
341 default:
342 /* Invalid data size */
343 *ActualDataSize = 0;
344 return STATUS_INVALID_PARAMETER;
345 }
346
347 /* Return the size of the data */
348 *ActualDataSize = DataSize;
349
350 /* Success! */
351 return STATUS_SUCCESS;
352 }
353
354 NTSTATUS
355 NTAPI
356 KdpSysCheckLowMemory(IN ULONG Flags)
357 {
358 UNIMPLEMENTED_DBGBREAK();
359 return STATUS_UNSUCCESSFUL;
360 }
361
362 NTSTATUS
363 NTAPI
364 KdpAllowDisable(VOID)
365 {
366 UNIMPLEMENTED_DBGBREAK();
367 return STATUS_ACCESS_DENIED;
368 }
369
370 /* EOF */