* Sync up to trunk r55544.
[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;
143 while (TRUE);
144 return STATUS_UNSUCCESSFUL;
145 }
146
147 NTSTATUS
148 NTAPI
149 KdpSysWriteBusData(IN ULONG BusDataType,
150 IN ULONG BusNumber,
151 IN ULONG SlotNumber,
152 IN ULONG Offset,
153 IN PVOID Buffer,
154 IN ULONG Length,
155 OUT PULONG ActualLength)
156 {
157 UNIMPLEMENTED;
158 while (TRUE);
159 return STATUS_UNSUCCESSFUL;
160 }
161
162 NTSTATUS
163 NTAPI
164 KdpSysReadControlSpace(IN ULONG Processor,
165 IN ULONG64 BaseAddress,
166 IN PVOID Buffer,
167 IN ULONG Length,
168 OUT PULONG ActualLength)
169 {
170 PVOID ControlStart;
171 PKPRCB Prcb = KiProcessorBlock[Processor];
172 PKIPCR Pcr = CONTAINING_RECORD(Prcb, KIPCR, Prcb);
173
174 switch (BaseAddress)
175 {
176 case AMD64_DEBUG_CONTROL_SPACE_KPCR:
177 /* Copy a pointer to the Pcr */
178 ControlStart = &Pcr;
179 *ActualLength = sizeof(PVOID);
180 break;
181
182 case AMD64_DEBUG_CONTROL_SPACE_KPRCB:
183 /* Copy a pointer to the Prcb */
184 ControlStart = &Prcb;
185 *ActualLength = sizeof(PVOID);
186 break;
187
188 case AMD64_DEBUG_CONTROL_SPACE_KSPECIAL:
189 /* Copy SpecialRegisters */
190 ControlStart = &Prcb->ProcessorState.SpecialRegisters;
191 *ActualLength = sizeof(KSPECIAL_REGISTERS);
192 break;
193
194 case AMD64_DEBUG_CONTROL_SPACE_KTHREAD:
195 /* Copy a pointer to the current Thread */
196 ControlStart = &Prcb->CurrentThread;
197 *ActualLength = sizeof(PVOID);
198 break;
199
200 default:
201 *ActualLength = 0;
202 ASSERT(FALSE);
203 return STATUS_UNSUCCESSFUL;
204 }
205
206 /* Copy the memory */
207 RtlCopyMemory(Buffer, ControlStart, min(Length, *ActualLength));
208
209 /* Finish up */
210 return STATUS_SUCCESS;
211 }
212
213 NTSTATUS
214 NTAPI
215 KdpSysWriteControlSpace(IN ULONG Processor,
216 IN ULONG64 BaseAddress,
217 IN PVOID Buffer,
218 IN ULONG Length,
219 OUT PULONG ActualLength)
220 {
221 PVOID ControlStart;
222 PKPRCB Prcb = KiProcessorBlock[Processor];
223
224 switch (BaseAddress)
225 {
226 case AMD64_DEBUG_CONTROL_SPACE_KSPECIAL:
227 /* Copy SpecialRegisters */
228 ControlStart = &Prcb->ProcessorState.SpecialRegisters;
229 *ActualLength = sizeof(KSPECIAL_REGISTERS);
230 break;
231
232 default:
233 *ActualLength = 0;
234 ASSERT(FALSE);
235 return STATUS_UNSUCCESSFUL;
236 }
237
238 /* Copy the memory */
239 RtlCopyMemory(ControlStart, Buffer, min(Length, *ActualLength));
240
241 return STATUS_SUCCESS;
242 }
243
244 NTSTATUS
245 NTAPI
246 KdpSysReadIoSpace(IN ULONG InterfaceType,
247 IN ULONG BusNumber,
248 IN ULONG AddressSpace,
249 IN ULONG64 IoAddress,
250 OUT PVOID DataValue,
251 IN ULONG DataSize,
252 OUT PULONG ActualDataSize)
253 {
254 /* Verify parameters */
255 if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)
256 {
257 /* No data was read */
258 *ActualDataSize = 0;
259 return STATUS_INVALID_PARAMETER;
260 }
261
262 /* Check for correct alignment */
263 if ((IoAddress & (DataSize - 1)))
264 {
265 /* Invalid alignment */
266 *ActualDataSize = 0;
267 return STATUS_DATATYPE_MISALIGNMENT;
268 }
269
270 switch (DataSize)
271 {
272 case sizeof(UCHAR):
273 /* Read one UCHAR */
274 *(PUCHAR)DataValue = READ_PORT_UCHAR((PUCHAR)IoAddress);
275 break;
276
277 case sizeof(USHORT):
278 /* Read one USHORT */
279 *(PUSHORT)DataValue = READ_PORT_USHORT((PUSHORT)IoAddress);
280 break;
281
282 case sizeof(ULONG):
283 /* Read one ULONG */
284 *(PULONG)DataValue = READ_PORT_ULONG((PULONG)IoAddress);
285 break;
286
287 default:
288 /* Invalid data size */
289 *ActualDataSize = 0;
290 return STATUS_INVALID_PARAMETER;
291 }
292
293 /* Return the size of the data */
294 *ActualDataSize = DataSize;
295
296 /* Success! */
297 return STATUS_SUCCESS;
298 }
299
300 NTSTATUS
301 NTAPI
302 KdpSysWriteIoSpace(IN ULONG InterfaceType,
303 IN ULONG BusNumber,
304 IN ULONG AddressSpace,
305 IN ULONG64 IoAddress,
306 IN PVOID DataValue,
307 IN ULONG DataSize,
308 OUT PULONG ActualDataSize)
309 {
310 /* Verify parameters */
311 if (InterfaceType != Isa || BusNumber != 0 || AddressSpace != 1)
312 {
313 /* No data was written */
314 *ActualDataSize = 0;
315 return STATUS_INVALID_PARAMETER;
316 }
317
318 /* Check for correct alignment */
319 if ((IoAddress & (DataSize - 1)))
320 {
321 /* Invalid alignment */
322 *ActualDataSize = 0;
323 return STATUS_DATATYPE_MISALIGNMENT;
324 }
325
326 switch (DataSize)
327 {
328 case sizeof(UCHAR):
329 /* Write one UCHAR */
330 WRITE_PORT_UCHAR((PUCHAR)IoAddress, *(PUCHAR)DataValue);
331 break;
332
333 case sizeof(USHORT):
334 /* Write one USHORT */
335 WRITE_PORT_USHORT((PUSHORT)IoAddress, *(PUSHORT)DataValue);
336 break;
337
338 case sizeof(ULONG):
339 /* Write one ULONG */
340 WRITE_PORT_ULONG((PULONG)IoAddress, *(PULONG)DataValue);
341 break;
342
343 default:
344 /* Invalid data size */
345 *ActualDataSize = 0;
346 return STATUS_INVALID_PARAMETER;
347 }
348
349 /* Return the size of the data */
350 *ActualDataSize = DataSize;
351
352 /* Success! */
353 return STATUS_SUCCESS;
354 }
355
356 NTSTATUS
357 NTAPI
358 KdpSysCheckLowMemory(IN ULONG Flags)
359 {
360 UNIMPLEMENTED;
361 while (TRUE);
362 return STATUS_UNSUCCESSFUL;
363 }
364
365 NTSTATUS
366 NTAPI
367 KdpAllowDisable(VOID)
368 {
369 UNIMPLEMENTED;
370 while (TRUE);
371 return STATUS_ACCESS_DENIED;
372 }