Merge trunk head (r43756)
[reactos.git] / reactos / ntoskrnl / kd64 / i386 / kdsup.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/i386/kdsup.c
5 * PURPOSE: KD support routines for x86
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Stefan Ginsberg (stefan.ginsberg@reactos.org)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 VOID
19 NTAPI
20 KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
21 {
22 /* Copy the version block */
23 RtlCopyMemory(Version, &KdVersionBlock, sizeof(DBGKD_GET_VERSION64));
24 }
25
26 VOID
27 NTAPI
28 KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,
29 IN PCONTEXT Context)
30 {
31 PKPRCB Prcb;
32 ULONG i;
33
34 /* Check for success */
35 if (NT_SUCCESS(State->u.Continue2.ContinueStatus))
36 {
37 /* Check if we're tracing */
38 if (State->u.Continue2.ControlSet.TraceFlag)
39 {
40 /* Enable TF */
41 Context->EFlags |= EFLAGS_TF;
42 }
43 else
44 {
45 /* Remove it */
46 Context->EFlags &= ~EFLAGS_TF;
47 }
48
49 /* Loop all processors */
50 for (i = 0; i < KeNumberProcessors; i++)
51 {
52 /* Get the PRCB and update DR7 and DR6 */
53 Prcb = KiProcessorBlock[i];
54 Prcb->ProcessorState.SpecialRegisters.KernelDr7 =
55 State->u.Continue2.ControlSet.Dr7;
56 Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0;
57 }
58
59 /* Check if we have new symbol information */
60 if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1)
61 {
62 /* Update it */
63 KdpCurrentSymbolStart =
64 State->u.Continue2.ControlSet.CurrentSymbolStart;
65 KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd;
66 }
67 }
68 }
69
70 VOID
71 NTAPI
72 KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
73 IN PCONTEXT Context)
74 {
75 PKPRCB Prcb = KeGetCurrentPrcb();
76
77 /* Copy i386 specific debug registers */
78 WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.
79 KernelDr6;
80 WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.
81 KernelDr7;
82
83 /* Copy i386 specific segments */
84 WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;
85 WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;
86 WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;
87 WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;
88
89 /* Copy EFlags */
90 WaitStateChange->ControlReport.EFlags = Context->EFlags;
91
92 /* Set Report Flags */
93 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
94 if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)
95 {
96 WaitStateChange->ControlReport.ReportFlags |= REPORT_STANDARD_CS;
97 }
98 }
99
100 NTSTATUS
101 NTAPI
102 KdpSysReadMsr(IN ULONG Msr,
103 OUT PLARGE_INTEGER MsrValue)
104 {
105 /* Wrap this in SEH in case the MSR doesn't exist */
106 //_SEH2_TRY
107 {
108 /* Read from the MSR */
109 MsrValue->QuadPart = RDMSR(Msr);
110 }
111 //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
112 {
113 /* Invalid MSR */
114 //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
115 }
116 //_SEH2_END;
117
118 /* Success */
119 return STATUS_SUCCESS;
120 }
121
122 NTSTATUS
123 NTAPI
124 KdpSysWriteMsr(IN ULONG Msr,
125 IN PLARGE_INTEGER MsrValue)
126 {
127 /* Wrap this in SEH in case the MSR doesn't exist */
128 //_SEH2_TRY
129 {
130 /* Write to the MSR */
131 WRMSR(Msr, MsrValue->QuadPart);
132 }
133 //_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
134 {
135 /* Invalid MSR */
136 //_SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
137 }
138 //_SEH2_END;
139
140 /* Success */
141 return STATUS_SUCCESS;
142 }
143
144 NTSTATUS
145 NTAPI
146 KdpSysReadBusData(IN ULONG BusDataType,
147 IN ULONG BusNumber,
148 IN ULONG SlotNumber,
149 IN ULONG Offset,
150 IN PVOID Buffer,
151 IN ULONG Length,
152 OUT PULONG ActualLength)
153 {
154 /* Just forward to HAL */
155 *ActualLength = HalGetBusDataByOffset(BusDataType,
156 BusNumber,
157 SlotNumber,
158 Buffer,
159 Offset,
160 Length);
161
162 /* Return status */
163 return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
164 }
165
166 NTSTATUS
167 NTAPI
168 KdpSysWriteBusData(IN ULONG BusDataType,
169 IN ULONG BusNumber,
170 IN ULONG SlotNumber,
171 IN ULONG Offset,
172 IN PVOID Buffer,
173 IN ULONG Length,
174 OUT PULONG ActualLength)
175 {
176 /* Just forward to HAL */
177 *ActualLength = HalSetBusDataByOffset(BusDataType,
178 BusNumber,
179 SlotNumber,
180 Buffer,
181 Offset,
182 Length);
183
184 /* Return status */
185 return (*ActualLength != 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
186 }
187
188 NTSTATUS
189 NTAPI
190 KdpSysReadControlSpace(IN ULONG Processor,
191 IN ULONG64 BaseAddress,
192 IN PVOID Buffer,
193 IN ULONG Length,
194 OUT PULONG ActualLength)
195 {
196 PVOID ControlStart;
197 ULONG RealLength;
198
199 /* Make sure that this is a valid request */
200 if ((BaseAddress < sizeof(KPROCESSOR_STATE)) &&
201 (Processor < KeNumberProcessors))
202 {
203 /* Get the actual length */
204 RealLength = sizeof(KPROCESSOR_STATE) - (ULONG_PTR)BaseAddress;
205 if (RealLength < Length) Length = RealLength;
206
207 /* Set the proper address */
208 ControlStart = (PVOID)((ULONG_PTR)BaseAddress +
209 (ULONG_PTR)&KiProcessorBlock[Processor]->
210 ProcessorState);
211
212 /* Copy the memory */
213 RtlCopyMemory(Buffer, ControlStart, Length);
214
215 /* Finish up */
216 *ActualLength = Length;
217 return STATUS_SUCCESS;
218 }
219 else
220 {
221 /* Invalid request */
222 *ActualLength = 0;
223 return STATUS_UNSUCCESSFUL;
224 }
225 }
226
227 NTSTATUS
228 NTAPI
229 KdpSysWriteControlSpace(IN ULONG Processor,
230 IN ULONG64 BaseAddress,
231 IN PVOID Buffer,
232 IN ULONG Length,
233 OUT PULONG ActualLength)
234 {
235 PVOID ControlStart;
236
237 /* Make sure that this is a valid request */
238 if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
239 (Processor < KeNumberProcessors))
240 {
241 /* Set the proper address */
242 ControlStart = (PVOID)((ULONG_PTR)BaseAddress +
243 (ULONG_PTR)&KiProcessorBlock[Processor]->
244 ProcessorState);
245
246 /* Copy the memory */
247 RtlCopyMemory(ControlStart, Buffer, Length);
248
249 /* Finish up */
250 *ActualLength = Length;
251 return STATUS_SUCCESS;
252 }
253 else
254 {
255 /* Invalid request */
256 *ActualLength = 0;
257 return STATUS_UNSUCCESSFUL;
258 }
259 }
260
261 NTSTATUS
262 NTAPI
263 KdpSysReadIoSpace(IN ULONG InterfaceType,
264 IN ULONG BusNumber,
265 IN ULONG AddressSpace,
266 IN ULONG64 IoAddress,
267 IN PVOID DataValue,
268 IN ULONG DataSize,
269 OUT PULONG ActualDataSize)
270 {
271 NTSTATUS Status;
272
273 /* Verify parameters */
274 if ((InterfaceType != Isa) ||
275 (BusNumber != 0) ||
276 (AddressSpace != 1))
277 {
278 /* Fail, we don't support this */
279 *ActualDataSize = 0;
280 return STATUS_UNSUCCESSFUL;
281 }
282
283 /* Check the size */
284 switch (DataSize)
285 {
286 case sizeof(UCHAR):
287
288 /* Read 1 byte */
289 *(PUCHAR)DataValue =
290 READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
291 *ActualDataSize = sizeof(UCHAR);
292 Status = STATUS_SUCCESS;
293 break;
294
295 case sizeof(USHORT):
296
297 /* Make sure the address is aligned */
298 if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
299 {
300 /* It isn't, bail out */
301 *ActualDataSize = 0;
302 Status = STATUS_DATATYPE_MISALIGNMENT;
303 break;
304 }
305
306 /* Read 2 bytes */
307 *(PUSHORT)DataValue =
308 READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress);
309 *ActualDataSize = sizeof(USHORT);
310 Status = STATUS_SUCCESS;
311 break;
312
313 case sizeof(ULONG):
314
315 /* Make sure the address is aligned */
316 if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
317 {
318 /* It isn't, bail out */
319 *ActualDataSize = 0;
320 Status = STATUS_DATATYPE_MISALIGNMENT;
321 break;
322 }
323
324 /* Read 4 bytes */
325 *(PULONG)DataValue =
326 READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress);
327 *ActualDataSize = sizeof(ULONG);
328 Status = STATUS_SUCCESS;
329 break;
330
331 default:
332
333 /* Invalid size, fail */
334 *ActualDataSize = 0;
335 Status = STATUS_INVALID_PARAMETER;
336 }
337
338 /* Return status */
339 return Status;
340 }
341
342 NTSTATUS
343 NTAPI
344 KdpSysWriteIoSpace(IN ULONG InterfaceType,
345 IN ULONG BusNumber,
346 IN ULONG AddressSpace,
347 IN ULONG64 IoAddress,
348 IN PVOID DataValue,
349 IN ULONG DataSize,
350 OUT PULONG ActualDataSize)
351 {
352 NTSTATUS Status;
353
354 /* Verify parameters */
355 if ((InterfaceType != Isa) ||
356 (BusNumber != 0) ||
357 (AddressSpace != 1))
358 {
359 /* Fail, we don't support this */
360 *ActualDataSize = 0;
361 return STATUS_UNSUCCESSFUL;
362 }
363
364 /* Check the size */
365 switch (DataSize)
366 {
367 case sizeof(UCHAR):
368
369 /* Write 1 byte */
370 WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
371 *(PUCHAR)DataValue);
372 *ActualDataSize = sizeof(UCHAR);
373 Status = STATUS_SUCCESS;
374 break;
375
376 case sizeof(USHORT):
377
378 /* Make sure the address is aligned */
379 if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
380 {
381 /* It isn't, bail out */
382 *ActualDataSize = 0;
383 Status = STATUS_DATATYPE_MISALIGNMENT;
384 break;
385 }
386
387 /* Write 2 bytes */
388 WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress,
389 *(PUSHORT)DataValue);
390 *ActualDataSize = sizeof(USHORT);
391 Status = STATUS_SUCCESS;
392 break;
393
394 case sizeof(ULONG):
395
396 /* Make sure the address is aligned */
397 if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
398 {
399 /* It isn't, bail out */
400 *ActualDataSize = 0;
401 Status = STATUS_DATATYPE_MISALIGNMENT;
402 break;
403 }
404
405 /* Write 4 bytes */
406 WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress,
407 *(PULONG)DataValue);
408 *ActualDataSize = sizeof(ULONG);
409 Status = STATUS_SUCCESS;
410 break;
411
412 default:
413
414 /* Invalid size, fail */
415 *ActualDataSize = 0;
416 Status = STATUS_INVALID_PARAMETER;
417 }
418
419 /* Return status */
420 return Status;
421 }
422
423 NTSTATUS
424 NTAPI
425 KdpSysCheckLowMemory(IN ULONG Flags)
426 {
427 /* Stubbed as we don't support PAE */
428 return STATUS_UNSUCCESSFUL;
429 }