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