- Add 'simple' implementation of MmDbgCopyMemory to read/write virtual memory in...
[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 /* Read the control state safely */
213 return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
214 ControlStart,
215 Length,
216 0,
217 MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
218 ActualLength);
219 }
220 else
221 {
222 /* Invalid request */
223 *ActualLength = 0;
224 return STATUS_UNSUCCESSFUL;
225 }
226 }
227
228 NTSTATUS
229 NTAPI
230 KdpSysWriteControlSpace(IN ULONG Processor,
231 IN ULONG64 BaseAddress,
232 IN PVOID Buffer,
233 IN ULONG Length,
234 OUT PULONG ActualLength)
235 {
236 PVOID ControlStart;
237
238 /* Make sure that this is a valid request */
239 if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
240 (Processor < KeNumberProcessors))
241 {
242 /* Set the proper address */
243 ControlStart = (PVOID)((ULONG_PTR)BaseAddress +
244 (ULONG_PTR)&KiProcessorBlock[Processor]->
245 ProcessorState);
246
247 /* Write the control state safely */
248 return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
249 ControlStart,
250 Length,
251 0,
252 MMDBG_COPY_UNSAFE,
253 ActualLength);
254 }
255 else
256 {
257 /* Invalid request */
258 *ActualLength = 0;
259 return STATUS_UNSUCCESSFUL;
260 }
261 }
262
263 NTSTATUS
264 NTAPI
265 KdpSysReadIoSpace(IN ULONG InterfaceType,
266 IN ULONG BusNumber,
267 IN ULONG AddressSpace,
268 IN ULONG64 IoAddress,
269 IN PVOID DataValue,
270 IN ULONG DataSize,
271 OUT PULONG ActualDataSize)
272 {
273 NTSTATUS Status;
274
275 /* Verify parameters */
276 if ((InterfaceType != Isa) ||
277 (BusNumber != 0) ||
278 (AddressSpace != 1))
279 {
280 /* Fail, we don't support this */
281 *ActualDataSize = 0;
282 return STATUS_UNSUCCESSFUL;
283 }
284
285 /* Check the size */
286 switch (DataSize)
287 {
288 case sizeof(UCHAR):
289
290 /* Read 1 byte */
291 *(PUCHAR)DataValue =
292 READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
293 *ActualDataSize = sizeof(UCHAR);
294 Status = STATUS_SUCCESS;
295 break;
296
297 case sizeof(USHORT):
298
299 /* Make sure the address is aligned */
300 if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
301 {
302 /* It isn't, bail out */
303 *ActualDataSize = 0;
304 Status = STATUS_DATATYPE_MISALIGNMENT;
305 break;
306 }
307
308 /* Read 2 bytes */
309 *(PUSHORT)DataValue =
310 READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress);
311 *ActualDataSize = sizeof(USHORT);
312 Status = STATUS_SUCCESS;
313 break;
314
315 case sizeof(ULONG):
316
317 /* Make sure the address is aligned */
318 if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
319 {
320 /* It isn't, bail out */
321 *ActualDataSize = 0;
322 Status = STATUS_DATATYPE_MISALIGNMENT;
323 break;
324 }
325
326 /* Read 4 bytes */
327 *(PULONG)DataValue =
328 READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress);
329 *ActualDataSize = sizeof(ULONG);
330 Status = STATUS_SUCCESS;
331 break;
332
333 default:
334
335 /* Invalid size, fail */
336 *ActualDataSize = 0;
337 Status = STATUS_INVALID_PARAMETER;
338 }
339
340 /* Return status */
341 return Status;
342 }
343
344 NTSTATUS
345 NTAPI
346 KdpSysWriteIoSpace(IN ULONG InterfaceType,
347 IN ULONG BusNumber,
348 IN ULONG AddressSpace,
349 IN ULONG64 IoAddress,
350 IN PVOID DataValue,
351 IN ULONG DataSize,
352 OUT PULONG ActualDataSize)
353 {
354 NTSTATUS Status;
355
356 /* Verify parameters */
357 if ((InterfaceType != Isa) ||
358 (BusNumber != 0) ||
359 (AddressSpace != 1))
360 {
361 /* Fail, we don't support this */
362 *ActualDataSize = 0;
363 return STATUS_UNSUCCESSFUL;
364 }
365
366 /* Check the size */
367 switch (DataSize)
368 {
369 case sizeof(UCHAR):
370
371 /* Write 1 byte */
372 WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
373 *(PUCHAR)DataValue);
374 *ActualDataSize = sizeof(UCHAR);
375 Status = STATUS_SUCCESS;
376 break;
377
378 case sizeof(USHORT):
379
380 /* Make sure the address is aligned */
381 if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
382 {
383 /* It isn't, bail out */
384 *ActualDataSize = 0;
385 Status = STATUS_DATATYPE_MISALIGNMENT;
386 break;
387 }
388
389 /* Write 2 bytes */
390 WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress,
391 *(PUSHORT)DataValue);
392 *ActualDataSize = sizeof(USHORT);
393 Status = STATUS_SUCCESS;
394 break;
395
396 case sizeof(ULONG):
397
398 /* Make sure the address is aligned */
399 if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
400 {
401 /* It isn't, bail out */
402 *ActualDataSize = 0;
403 Status = STATUS_DATATYPE_MISALIGNMENT;
404 break;
405 }
406
407 /* Write 4 bytes */
408 WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress,
409 *(PULONG)DataValue);
410 *ActualDataSize = sizeof(ULONG);
411 Status = STATUS_SUCCESS;
412 break;
413
414 default:
415
416 /* Invalid size, fail */
417 *ActualDataSize = 0;
418 Status = STATUS_INVALID_PARAMETER;
419 }
420
421 /* Return status */
422 return Status;
423 }
424
425 NTSTATUS
426 NTAPI
427 KdpSysCheckLowMemory(IN ULONG Flags)
428 {
429 /* Stubbed as we don't support PAE */
430 return STATUS_UNSUCCESSFUL;
431 }