Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / ntoskrnl / kd64 / i386 / kdx86.c
diff --git a/ntoskrnl/kd64/i386/kdx86.c b/ntoskrnl/kd64/i386/kdx86.c
new file mode 100644 (file)
index 0000000..a70eb46
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/kd64/i386/kdx86.c
+ * PURPOSE:         KD support routines for x86
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ *                  Stefan Ginsberg (stefan.ginsberg@reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State,
+                  IN PCONTEXT Context)
+{
+    PKPRCB Prcb;
+    ULONG i;
+
+    /* Check for success */
+    if (NT_SUCCESS(State->u.Continue2.ContinueStatus))
+    {
+        /* Check if we're tracing */
+        if (State->u.Continue2.ControlSet.TraceFlag)
+        {
+            /* Enable TF */
+            Context->EFlags |= EFLAGS_TF;
+        }
+        else
+        {
+            /* Remove it */
+            Context->EFlags &= ~EFLAGS_TF;
+        }
+
+        /* Loop all processors */
+        for (i = 0; i < KeNumberProcessors; i++)
+        {
+            /* Get the PRCB and update DR7 and DR6 */
+            Prcb = KiProcessorBlock[i];
+            Prcb->ProcessorState.SpecialRegisters.KernelDr7 =
+                State->u.Continue2.ControlSet.Dr7;
+            Prcb->ProcessorState.SpecialRegisters.KernelDr6 = 0;
+        }
+
+        /* Check if we have new symbol information */
+        if (State->u.Continue2.ControlSet.CurrentSymbolStart != 1)
+        {
+            /* Update it */
+            KdpCurrentSymbolStart =
+                State->u.Continue2.ControlSet.CurrentSymbolStart;
+            KdpCurrentSymbolEnd= State->u.Continue2.ControlSet.CurrentSymbolEnd;
+        }
+    }
+}
+
+VOID
+NTAPI
+KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange,
+                   IN PCONTEXT Context)
+{
+    PKPRCB Prcb = KeGetCurrentPrcb();
+
+    /* Copy i386 specific debug registers */
+    WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.
+                                         KernelDr6;
+    WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.
+                                         KernelDr7;
+
+    /* Copy i386 specific segments */
+    WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;
+    WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;
+    WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;
+    WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;
+
+    /* Copy EFlags */
+    WaitStateChange->ControlReport.EFlags = Context->EFlags;
+
+    /* Set Report Flags */
+    WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
+    if (WaitStateChange->ControlReport.SegCs == KGDT_R0_CODE)
+    {
+        WaitStateChange->ControlReport.ReportFlags |= REPORT_STANDARD_CS;
+    }
+}
+
+NTSTATUS
+NTAPI
+KdpSysReadMsr(IN ULONG Msr,
+              OUT PLARGE_INTEGER MsrValue)
+{
+    /* Wrap this in SEH in case the MSR doesn't exist */
+    _SEH2_TRY
+    {
+        /* Read from the MSR */
+        MsrValue->QuadPart = __readmsr(Msr);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Invalid MSR */
+        _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
+    }
+    _SEH2_END;
+
+    /* Success */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdpSysWriteMsr(IN ULONG Msr,
+               IN PLARGE_INTEGER MsrValue)
+{
+    /* Wrap this in SEH in case the MSR doesn't exist */
+    _SEH2_TRY
+    {
+        /* Write to the MSR */
+        __writemsr(Msr, MsrValue->QuadPart);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        /* Invalid MSR */
+        _SEH2_YIELD(return STATUS_NO_SUCH_DEVICE);
+    }
+    _SEH2_END;
+
+    /* Success */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdpSysReadBusData(IN ULONG BusDataType,
+                  IN ULONG BusNumber,
+                  IN ULONG SlotNumber,
+                  IN ULONG Offset,
+                  IN PVOID Buffer,
+                  IN ULONG Length,
+                  OUT PULONG ActualLength)
+{
+    /* Just forward to HAL */
+    *ActualLength = HalGetBusDataByOffset(BusDataType,
+                                          BusNumber,
+                                          SlotNumber,
+                                          Buffer,
+                                          Offset,
+                                          Length);
+
+    /* Return status */
+    return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+KdpSysWriteBusData(IN ULONG BusDataType,
+                   IN ULONG BusNumber,
+                   IN ULONG SlotNumber,
+                   IN ULONG Offset,
+                   IN PVOID Buffer,
+                   IN ULONG Length,
+                   OUT PULONG ActualLength)
+{
+    /* Just forward to HAL */
+    *ActualLength = HalSetBusDataByOffset(BusDataType,
+                                          BusNumber,
+                                          SlotNumber,
+                                          Buffer,
+                                          Offset,
+                                          Length);
+
+    /* Return status */
+    return *ActualLength != 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+KdpSysReadControlSpace(IN ULONG Processor,
+                       IN ULONG64 BaseAddress,
+                       IN PVOID Buffer,
+                       IN ULONG Length,
+                       OUT PULONG ActualLength)
+{
+    PVOID ControlStart;
+    ULONG RealLength;
+
+    /* Make sure that this is a valid request */
+    if ((BaseAddress < sizeof(KPROCESSOR_STATE)) &&
+        (Processor < KeNumberProcessors))
+    {
+        /* Get the actual length */
+        RealLength = sizeof(KPROCESSOR_STATE) - (ULONG_PTR)BaseAddress;
+        if (RealLength < Length) Length = RealLength;
+
+        /* Set the proper address */
+        ControlStart = (PVOID)((ULONG_PTR)BaseAddress +
+                               (ULONG_PTR)&KiProcessorBlock[Processor]->
+                                           ProcessorState);
+
+        /* Read the control state safely */
+        return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
+                                   ControlStart,
+                                   Length,
+                                   0,
+                                   MMDBG_COPY_UNSAFE | MMDBG_COPY_WRITE,
+                                   ActualLength);
+    }
+    else
+    {
+        /* Invalid request */
+        *ActualLength = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+}
+
+NTSTATUS
+NTAPI
+KdpSysWriteControlSpace(IN ULONG Processor,
+                        IN ULONG64 BaseAddress,
+                        IN PVOID Buffer,
+                        IN ULONG Length,
+                        OUT PULONG ActualLength)
+{
+    PVOID ControlStart;
+
+    /* Make sure that this is a valid request */
+    if (((BaseAddress + Length) <= sizeof(KPROCESSOR_STATE)) &&
+        (Processor < KeNumberProcessors))
+    {
+        /* Set the proper address */
+        ControlStart = (PVOID)((ULONG_PTR)BaseAddress +
+                               (ULONG_PTR)&KiProcessorBlock[Processor]->
+                                           ProcessorState);
+
+        /* Write the control state safely */
+        return KdpCopyMemoryChunks((ULONG_PTR)Buffer,
+                                   ControlStart,
+                                   Length,
+                                   0,
+                                   MMDBG_COPY_UNSAFE,
+                                   ActualLength);
+    }
+    else
+    {
+        /* Invalid request */
+        *ActualLength = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+}
+
+NTSTATUS
+NTAPI
+KdpSysReadIoSpace(IN ULONG InterfaceType,
+                  IN ULONG BusNumber,
+                  IN ULONG AddressSpace,
+                  IN ULONG64 IoAddress,
+                  IN PVOID DataValue,
+                  IN ULONG DataSize,
+                  OUT PULONG ActualDataSize)
+{
+    NTSTATUS Status;
+
+    /* Verify parameters */
+    if ((InterfaceType != Isa) ||
+        (BusNumber != 0) ||
+        (AddressSpace != 1))
+    {
+        /* Fail, we don't support this */
+        *ActualDataSize = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Check the size */
+    switch (DataSize)
+    {
+        case sizeof(UCHAR):
+
+            /* Read 1 byte */
+            *(PUCHAR)DataValue =
+                READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(UCHAR);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(USHORT):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Read 2 bytes */
+            *(PUSHORT)DataValue =
+                READ_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(USHORT);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(ULONG):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Read 4 bytes */
+            *(PULONG)DataValue =
+                READ_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress);
+            *ActualDataSize = sizeof(ULONG);
+            Status = STATUS_SUCCESS;
+            break;
+
+        default:
+
+            /* Invalid size, fail */
+            *ActualDataSize = 0;
+            Status = STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+KdpSysWriteIoSpace(IN ULONG InterfaceType,
+                   IN ULONG BusNumber,
+                   IN ULONG AddressSpace,
+                   IN ULONG64 IoAddress,
+                   IN PVOID DataValue,
+                   IN ULONG DataSize,
+                   OUT PULONG ActualDataSize)
+{
+    NTSTATUS Status;
+
+    /* Verify parameters */
+    if ((InterfaceType != Isa) ||
+        (BusNumber != 0) ||
+        (AddressSpace != 1))
+    {
+        /* Fail, we don't support this */
+        *ActualDataSize = 0;
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Check the size */
+    switch (DataSize)
+    {
+        case sizeof(UCHAR):
+
+            /* Write 1 byte */
+            WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)IoAddress,
+                             *(PUCHAR)DataValue);
+            *ActualDataSize = sizeof(UCHAR);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(USHORT):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(USHORT) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Write 2 bytes */
+            WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)IoAddress,
+                             *(PUSHORT)DataValue);
+            *ActualDataSize = sizeof(USHORT);
+            Status = STATUS_SUCCESS;
+            break;
+
+        case sizeof(ULONG):
+
+            /* Make sure the address is aligned */
+            if ((IoAddress & (sizeof(ULONG) - 1)) != 0)
+            {
+                /* It isn't, bail out */
+                *ActualDataSize = 0;
+                Status = STATUS_DATATYPE_MISALIGNMENT;
+                break;
+            }
+
+            /* Write 4 bytes */
+            WRITE_PORT_ULONG((PULONG)(ULONG_PTR)IoAddress,
+                             *(PULONG)DataValue);
+            *ActualDataSize = sizeof(ULONG);
+            Status = STATUS_SUCCESS;
+            break;
+
+        default:
+
+            /* Invalid size, fail */
+            *ActualDataSize = 0;
+            Status = STATUS_INVALID_PARAMETER;
+    }
+
+    /* Return status */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+KdpSysCheckLowMemory(IN ULONG Flags)
+{
+    /* Stubbed as we don't support PAE */
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+KdpAllowDisable(VOID)
+{
+    LONG i;
+    ULONG Dr7;
+
+    /* Loop every processor */
+    for (i = 0; i < KeNumberProcessors; i++)
+    {
+        /* Get its DR7 */
+        Dr7 =  KiProcessorBlock[i]->ProcessorState.SpecialRegisters.KernelDr7;
+
+        /* Check if any processor breakpoints are active */
+        if (Dr7 != 0)
+        {
+            /* We can't allow running without a debugger then */
+            return STATUS_ACCESS_DENIED;
+        }
+    }
+
+    /* No processor breakpoints; allow disabling the debugger */
+    return STATUS_SUCCESS;
+}