[ros-diffs] [tkreuzer] 43674: Rework kdcom, try to make it "portable", now in kddll folder, where other versions like kdusb and kd1394 can have a warm place, too. It still has issues.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Oct 21 22:03:27 CEST 2009


Author: tkreuzer
Date: Wed Oct 21 22:03:27 2009
New Revision: 43674

URL: http://svn.reactos.org/svn/reactos?rev=43674&view=rev
Log:
Rework kdcom, try to make it "portable", now in kddll folder, where other versions like kdusb and kd1394 can have a warm place, too. It still has issues.

Added:
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec   (with props)
    branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c   (with props)
Modified:
    branches/ros-amd64-bringup/reactos/drivers/base/directory.rbuild

Modified: branches/ros-amd64-bringup/reactos/drivers/base/directory.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/directory.rbuild?rev=43674&r1=43673&r2=43674&view=diff
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/directory.rbuild [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/drivers/base/directory.rbuild [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -7,8 +7,11 @@
 <directory name="bootvid">
 	<xi:include href="bootvid/bootvid.rbuild" />
 </directory>
-<directory name="kdcom">
+<!--directory name="kdcom">
     <xi:include href="kdcom/kdcom.rbuild" />
+</directory-->
+<directory name="kddll">
+    <xi:include href="kddll/kddll.rbuild" />
 </directory>
 <directory name="null">
 	<xi:include href="null/null.rbuild" />

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Wed Oct 21 22:03:27 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
    bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
    tsvn:logminsize = 10

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,294 @@
+/*
+ * COPYRIGHT:       GPL, see COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/base/kddll/kdcom.c
+ * PURPOSE:         COM port functions for the kernel debugger.
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer at ewactos.org)
+ */
+
+#include "kddll.h"
+#include "kdcom.h"
+
+/* Define wait timeout value. */
+#define REPEAT_COUNT (1000 * 1000)
+
+/* serial debug connection */
+#define DEFAULT_DEBUG_PORT      2 /* COM2 */
+#define DEFAULT_DEBUG_COM1_IRQ  4 /* COM1 IRQ */
+#define DEFAULT_DEBUG_COM2_IRQ  3 /* COM2 IRQ */
+#define DEFAULT_DEBUG_BAUD_RATE 115200 /* 115200 Baud */
+
+#define DEFAULT_BAUD_RATE    19200
+
+
+#if defined(_M_IX86) || defined(_M_AMD64)
+const ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+#elif defined(_M_PPC)
+const ULONG BaseArray[2] = {0, 0x800003f8};
+#elif defined(_M_MIPS)
+const ULONG BaseArray[3] = {0, 0x80006000, 0x80007000};
+#elif defined(_M_ARM)
+const ULONG BaseArray[2] = {0, 0xF1012000};
+#else
+#error Unknown architecture
+#endif
+
+/* GLOBALS ********************************************************************/
+
+PUCHAR ComPortBase;
+ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
+ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
+ULONG ComPortIrq = 0;
+
+
+NTSTATUS
+NTAPI
+KdpPortInitialize()
+{
+    ULONG Mode;
+
+KdpDbgPrint("KdpPortInitialize\n");
+
+    /* Enable loop mode (set Bit 4 of the MCR) */
+    WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP);
+
+    /* Clear all modem output bits */
+    WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_LOOP);
+
+    /* The upper nibble of the MSR (modem output bits) must be
+     * equal to the lower nibble of the MCR (modem input bits) */
+    if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0x00)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Set all modem output bits */
+    WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_ALL);
+
+    /* The upper nibble of the MSR (modem output bits) must be
+     * equal to the lower nibble of the MCR (modem input bits) */
+    if ((READ_PORT_UCHAR(ComPortBase + COM_MSR) & 0xF0) != 0xF0)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Enable FIFO */
+    WRITE_PORT_UCHAR(ComPortBase + COM_FCR,
+                     FCR_ENABLE_FIFO | FCR_CLEAR_RCVR | FCR_CLEAR_XMIT);
+
+    /* Disable interrupts */
+    WRITE_PORT_UCHAR(ComPortBase + COM_LCR, 0);
+    WRITE_PORT_UCHAR(ComPortBase + COM_IEN, 0);
+
+    /* Enable on DTR and RTS  */
+    WRITE_PORT_UCHAR(ComPortBase + COM_MCR, MCR_DTR | MCR_RTS);
+
+    /* Set DLAB */
+    WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_DLAB);
+
+    /* Set baud rate */
+    Mode = 115200 / ComPortBaudRate;
+    WRITE_PORT_UCHAR(ComPortBase + COM_DLL, (UCHAR)(Mode & 0xff));
+    WRITE_PORT_UCHAR(ComPortBase + COM_DLM, (UCHAR)((Mode >> 8) & 0xff));
+
+    /* Reset DLAB and set 8 data bits, 1 stop bit, no parity, no break */
+    WRITE_PORT_UCHAR(ComPortBase + COM_LCR, LCR_CS8 | LCR_ST1 | LCR_PNO);
+
+    /* Check for 16450/16550 scratch register */
+    WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0xff);
+    if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0xff)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+    WRITE_PORT_UCHAR(ComPortBase + COM_SCR, 0x00);
+    if (READ_PORT_UCHAR(ComPortBase + COM_SCR) != 0x00)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * \name KdDebuggerInitialize0
+ * \brief Phase 0 initialization.
+ * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
+ * \return Status
+ */
+NTSTATUS
+NTAPI
+KdDebuggerInitialize0(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
+{
+    PCHAR CommandLine, PortString, BaudString, IrqString;
+    ULONG Value;
+
+    /* Check if e have a LoaderBlock */
+    if (LoaderBlock)
+    {
+        /* Get the Command Line */
+        CommandLine = LoaderBlock->LoadOptions;
+
+        /* Upcase it */
+        _strupr(CommandLine);
+
+        /* Get the port and baud rate */
+        PortString = strstr(CommandLine, "DEBUGPORT");
+        BaudString = strstr(CommandLine, "BAUDRATE");
+        IrqString = strstr(CommandLine, "IRQ");
+
+        /* Check if we got the /DEBUGPORT parameter */
+        if (PortString)
+        {
+            /* Move past the actual string, to reach the port*/
+            PortString += strlen("DEBUGPORT");
+
+            /* Now get past any spaces and skip the equal sign */
+            while (*PortString == ' ') PortString++;
+            PortString++;
+
+            /* Do we have a serial port? */
+            if (strncmp(PortString, "COM", 3) != 0)
+            {
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            /* Gheck for a valid Serial Port */
+            PortString += 3;
+            Value = atol(PortString);
+            if (Value > 4)
+            {
+                return STATUS_INVALID_PARAMETER;
+            }
+
+            /* Set the port to use */
+            ComPortNumber = Value;
+       }
+
+        /* Check if we got a baud rate */
+        if (BaudString)
+        {
+            /* Move past the actual string, to reach the rate */
+            BaudString += strlen("BAUDRATE");
+
+            /* Now get past any spaces */
+            while (*BaudString == ' ') BaudString++;
+
+            /* And make sure we have a rate */
+            if (*BaudString)
+            {
+                /* Read and set it */
+                Value = atol(BaudString + 1);
+                if (Value) ComPortBaudRate = Value;
+            }
+        }
+
+        /* Check Serial Port Settings [IRQ] */
+        if (IrqString)
+        {
+            /* Move past the actual string, to reach the rate */
+            IrqString += strlen("IRQ");
+
+            /* Now get past any spaces */
+            while (*IrqString == ' ') IrqString++;
+
+            /* And make sure we have an IRQ */
+            if (*IrqString)
+            {
+                /* Read and set it */
+                Value = atol(IrqString + 1);
+                if (Value) ComPortIrq = Value;
+            }
+        }
+    }
+
+    // HACK use com1 for FrLdrDbg, com2 for WinDbg
+    ComPortNumber = 2;
+
+    /* Get base address */
+    ComPortBase = UlongToPtr(BaseArray[ComPortNumber]);
+
+    /* Initialize the port */
+    return KdpPortInitialize();
+}
+
+VOID
+NTAPI
+KdpSendByte(IN BYTE Byte)
+{
+    /* Wait for the port to be ready */
+    while ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_TBE) == 0);
+
+    /* Send the byte */
+    WRITE_PORT_UCHAR(ComPortBase + COM_DAT, Byte);
+}
+
+KDP_STATUS
+NTAPI
+KdpPollByte(OUT PBYTE OutByte)
+{
+    /* Check if data is available */
+    if ((READ_PORT_UCHAR(ComPortBase + COM_LSR) & LSR_DR))
+    {
+        /* Yes, return the byte */
+        *OutByte = READ_PORT_UCHAR(ComPortBase + COM_DAT);
+        return KDP_PACKET_RECEIVED;
+    }
+
+    /* Timed out */
+    return KDP_PACKET_TIMEOUT;
+}
+
+KDP_STATUS
+NTAPI
+KdpReceiveByte(OUT PBYTE OutByte)
+{
+    ULONG Repeats = REPEAT_COUNT;
+
+    while (Repeats--)
+    {
+        /* Check if data is available */
+        if (KdpPollByte(OutByte) == KDP_PACKET_RECEIVED)
+        {
+            /* We successfully got a byte */
+            return KDP_PACKET_RECEIVED;
+        }
+    }
+
+    /* Timed out */
+    return KDP_PACKET_TIMEOUT;
+}
+
+KDP_STATUS
+NTAPI
+KdpPollBreakIn()
+{
+    UCHAR Byte;
+    if (KdpPollByte(&Byte) == KDP_PACKET_RECEIVED)
+    {
+        if (Byte == BREAKIN_PACKET_BYTE)
+        {
+            return KDP_PACKET_RECEIVED;
+        }
+    }
+    return KDP_PACKET_TIMEOUT;
+}
+
+NTSTATUS
+NTAPI
+KdSave(
+    IN BOOLEAN SleepTransition)
+{
+    /* Nothing to do on COM ports */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdRestore(
+    IN BOOLEAN SleepTransition)
+{
+    /* Nothing to do on COM ports */
+    return STATUS_SUCCESS;
+}
+

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,53 @@
+/*
+ * COPYRIGHT:       GPL, see COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/base/kddll/kdcom.h
+ * PURPOSE:         COM port definitions for the kernel debugger.
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer at ewactos.org)
+ */
+
+#define COM_DAT 0x00
+#define COM_IEN 0x01    // interrupt enable register
+#define COM_FCR 0x02    // FIFO Control Register
+#define COM_LCR 0x03    // line control registers
+#define COM_MCR 0x04    // modem control reg
+#define COM_LSR 0x05    // line status register
+#define COM_MSR 0x06    // modem status register
+#define COM_SCR 0x07    // scratch register
+#define COM_DLL 0x00    // divisor latch least sig
+#define COM_DLM 0x01    // divisor latch most sig
+
+#define IEN_ERDA   0x01
+#define IEN_ETHRE  0x02
+#define IEN_ERLSI  0x04
+#define IEN_EMS    0x08
+#define IEN_ALL    0x0F
+#define FCR_ENABLE_FIFO 0x01
+#define FCR_CLEAR_RCVR  0x02
+#define FCR_CLEAR_XMIT  0x04
+#define LCR_CS5 0x00
+#define LCR_CS6 0x01
+#define LCR_CS7 0x02
+#define LCR_CS8 0x03
+#define LCR_ST1 0x00
+#define LCR_ST2 0x04
+#define LCR_PNO 0x00
+#define LCR_POD 0x08
+#define LCR_PEV 0x18
+#define LCR_PMK 0x28
+#define LCR_PSP 0x38
+#define LCR_BRK 0x40
+#define LCR_DLAB 0x80
+#define MCR_DTR  0x01
+#define MCR_RTS  0x02
+#define MCR_OUT1 0x04    // general purpose output.
+#define MCR_OUT2 0x08
+#define MCR_LOOP 0x10    // enables loopback testing mode
+#define MCR_ALL (MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2 | MCR_LOOP)
+#define LSR_DR  0x01
+#define LSR_TBE 0x20
+#define MSR_CTS  0x10    // (complemented) state of clear to send (CTS).
+#define MSR_DSR  0x20    // (complemented) state of data set ready (DSR).
+#define MSR_RI   0x40    // (complemented) state of ring indicator (RI).
+#define MSR_DCD  0x80    // (complemented) state of data carrier detect (DCD).
+

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdcom.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,407 @@
+/*
+ * COPYRIGHT:       GPL, see COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/base/kddll/kddll.c
+ * PURPOSE:         Base functions for the kernel debugger.
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer at ewactos.org)
+ */
+
+#include "kddll.h"
+
+/* GLOBALS ********************************************************************/
+
+ULONG CurrentPacketId = INITIAL_PACKET_ID;
+
+// HACK!!!
+DBGRNT KdpDbgPrint = 0;
+
+
+/******************************************************************************
+ * \name KdpCalculateChecksum
+ * \brief Calculates the checksum for the packet data.
+ * \param Buffer Pointer to the packet data.
+ * \param Length Length of data in bytes.
+ * \return The calculated checksum.
+ * \sa http://www.vista-xp.co.uk/forums/technical-reference-library/2540-basics-debugging.html
+ */
+ULONG
+NTAPI
+KdpCalculateChecksum(
+    IN PVOID Buffer,
+    IN ULONG Length)
+{
+    ULONG i, Checksum = 0;
+
+    for (i = 0; i < Length; i++)
+    {
+        Checksum += ((PUCHAR)Buffer)[i];
+    }
+
+    return Checksum;
+}
+
+VOID
+NTAPI
+KdpSendControlPacket(
+    IN USHORT PacketType,
+    IN ULONG PacketId OPTIONAL)
+{
+    KD_PACKET Packet;
+
+    Packet.PacketLeader = CONTROL_PACKET_LEADER;
+    Packet.PacketId = PacketId;
+    Packet.ByteCount = 0;
+    Packet.Checksum = 0;
+    Packet.PacketType = PacketType;
+
+    KdpSendBuffer(&Packet, sizeof(KD_PACKET));
+}
+
+
+/** Public exported functions *************************************************/
+
+NTSTATUS
+NTAPI
+DriverEntry(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PUNICODE_STRING RegistryPath)
+{
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdD0Transition(VOID)
+{
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+KdD3Transition(VOID)
+{
+    return STATUS_SUCCESS;
+}
+
+
+/******************************************************************************
+ * \name KdDebuggerInitialize1
+ * \brief Phase 1 initialization.
+ * \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
+ * \return Status
+ */
+NTSTATUS
+NTAPI
+KdDebuggerInitialize1(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
+{
+    // HACK: misuse this function to get a pointer to FrLdrDbgPrint
+    KdpDbgPrint = (PVOID)LoaderBlock;
+    KdpDbgPrint("KdDebuggerInitialize1\n");
+
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/******************************************************************************
+ * \name KdReceivePacket
+ * \brief Receive a packet from the KD port.
+ * \param [in] PacketType Describes the type of the packet to receive.
+ *        This can be one of the PACKET_TYPE_ constants.
+ * \param [out] MessageHeader Pointer to a STRING structure for the header.
+ * \param [out] MessageData Pointer to a STRING structure for the data.
+ * \return KdPacketReceived if successful, KdPacketTimedOut if the receive
+ *         timed out, KdPacketNeedsResend to signal that the last packet needs
+ *         to be sent again.
+ * \note If PacketType is PACKET_TYPE_KD_POLL_BREAKIN, the function doesn't
+ *       wait for any data, but returns KdPacketTimedOut instantly if no breakin
+ *       packet byte is received.
+ * \sa http://www.nynaeve.net/?p=169
+ */
+KDP_STATUS
+NTAPI
+KdReceivePacket(
+    IN ULONG PacketType,
+    OUT PSTRING MessageHeader,
+    OUT PSTRING MessageData,
+    OUT PULONG DataLength,
+    IN OUT PKD_CONTEXT Context)
+{
+    UCHAR Byte = 0;
+    KDP_STATUS KdStatus;
+    KD_PACKET Packet;
+    ULONG Checksum;
+
+    /* Special handling for breakin packet */
+    if(PacketType == PACKET_TYPE_KD_POLL_BREAKIN)
+    {
+        return KdpPollBreakIn();
+    }
+
+    for (;;)
+    {
+        /* Step 1 - Read PacketLeader */
+        KdStatus = KdpReceivePacketLeader(&Packet.PacketLeader);
+        if (KdStatus != KDP_PACKET_RECEIVED)
+        {
+            /* Couldn't read a correct packet leader.  */
+            return KdStatus;
+        }
+
+        /* Step 2 - Read PacketType */
+        KdStatus = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT));
+        if (KdStatus != KDP_PACKET_RECEIVED)
+        {
+            /* Didn't receive a PacketType or PacketType is bad. Start over. */
+            continue;
+        }
+
+        /* Step 3 - Read ByteCount */
+        KdStatus = KdpReceiveBuffer(&Packet.ByteCount, sizeof(USHORT));
+        if (KdStatus != KDP_PACKET_RECEIVED || Packet.ByteCount > PACKET_MAX_SIZE)
+        {
+            /* Didn't receive ByteCount or it's too big. Start over. */
+            continue;
+        }
+
+        /* Step 4 - Read PacketId */
+        KdStatus = KdpReceiveBuffer(&Packet.PacketId, sizeof(ULONG));
+        if (KdStatus != KDP_PACKET_RECEIVED)
+        {
+            /* Didn't receive PacketId. Start over. */
+            continue;
+        }
+
+/*
+        if (Packet.PacketId != ExpectedPacketId)
+        {
+            // Ask for a resend!
+            continue;
+        }
+*/
+
+        /* Step 5 - Read Checksum */
+        KdStatus = KdpReceiveBuffer(&Packet.Checksum, sizeof(ULONG));
+        if (KdStatus != KDP_PACKET_RECEIVED)
+        {
+            /* Didn't receive Checksum. Start over. */
+            continue;
+        }
+
+        /* Step 6 - Handle control packets */
+        if (Packet.PacketLeader == CONTROL_PACKET_LEADER)
+        {
+            switch (Packet.PacketType)
+            {
+                case PACKET_TYPE_KD_ACKNOWLEDGE:
+                    if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
+                    {
+                        /* Remote acknowledges the last packet */
+                        CurrentPacketId ^= 1;
+                        return KDP_PACKET_RECEIVED;
+                    }
+                    /* That's not what we were waiting for, start over. */
+                    continue;
+
+                case PACKET_TYPE_KD_RESET:
+                    KdpDbgPrint("KdReceivePacket - got a reset packet\n");
+                    KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
+                    CurrentPacketId = INITIAL_PACKET_ID;
+                    /* Fall through */
+
+                case PACKET_TYPE_KD_RESEND:
+                    /* Remote wants us to resend the last packet */
+                    return KDP_PACKET_RESEND;
+
+                default:
+                    KdpDbgPrint("KdReceivePacket - got unknown control packet\n");
+                    return KDP_PACKET_RESEND;
+            }
+        }
+
+        /* Did we wait for an ack packet? */
+        if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
+        {
+            /* We received something different, start over */
+            continue;
+        }
+
+        /* Did we get the right packet type? */
+        if (PacketType != Packet.PacketType)
+        {
+            /* We received something different, start over */
+            continue;
+        }
+
+        /* Get size of the message header */
+        switch (Packet.PacketType)
+        {
+            case PACKET_TYPE_KD_STATE_CHANGE64:
+                MessageHeader->Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
+                break;
+
+            case PACKET_TYPE_KD_STATE_MANIPULATE:
+                MessageHeader->Length = sizeof(DBGKD_MANIPULATE_STATE64);
+                break;
+
+            case PACKET_TYPE_KD_DEBUG_IO:
+                MessageHeader->Length = sizeof(DBGKD_DEBUG_IO);
+                break;
+
+            default:
+                KdpDbgPrint("KdReceivePacket - unknown PacketType\n");
+                return KDP_PACKET_RESEND;
+        }
+
+//KdpDbgPrint("KdReceivePacket - got normal PacketType\n");
+
+        /* Packet smaller than expected? */
+        if (MessageHeader->Length > Packet.ByteCount)
+        {
+            KdpDbgPrint("KdReceivePacket - too few data (%d) for type %d\n",
+                          Packet.ByteCount, MessageHeader->Length);
+            MessageHeader->Length = Packet.ByteCount;
+        }
+
+//KdpDbgPrint("KdReceivePacket - got normal PacketType, Buffer = %p\n", MessageHeader->Buffer);
+
+        /* Receive the message header data */
+        KdStatus = KdpReceiveBuffer(MessageHeader->Buffer,
+                                   MessageHeader->Length);
+        if (KdStatus != KDP_PACKET_RECEIVED)
+        {
+            /* Didn't receive data. Start over. */
+            KdpDbgPrint("KdReceivePacket - Didn't receive message header data. Start over\n");
+            continue;
+        }
+
+//KdpDbgPrint("KdReceivePacket - got normal PacketType 3\n");
+
+        /* Calculate checksum for the header data */
+        Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
+                                        MessageHeader->Length);
+
+        /* Shall we receive messsage data? */
+        if (MessageData)
+        {
+            /* Calculate the length of the message data */
+            MessageData->Length = Packet.ByteCount - MessageHeader->Length;
+
+            /* Do we have data? */
+            if (MessageData->Length)
+            {
+                KdpDbgPrint("KdReceivePacket - got data\n");
+
+                /* Receive the message data */
+                KdStatus = KdpReceiveBuffer(MessageData->Buffer,
+                                           MessageData->Length);
+                if (KdStatus != KDP_PACKET_RECEIVED)
+                {
+                    /* Didn't receive data. Start over. */
+                    KdpDbgPrint("KdReceivePacket - Didn't receive message data. Start over\n");
+                    continue;
+                }
+
+                /* Add cheksum for message data */
+                Checksum += KdpCalculateChecksum(MessageData->Buffer,
+                                                 MessageData->Length);
+            }
+        }
+
+        /* Compare checksum */
+        if (Packet.Checksum != Checksum)
+        {
+            KdpSendControlPacket(PACKET_TYPE_KD_RESEND, CurrentPacketId);
+            KdpDbgPrint("KdReceivePacket - wrong cheksum, got %x, calculated %x\n",
+                          Packet.Checksum, Checksum);
+            continue;
+        }
+
+        /* We must receive a PACKET_TRAILING_BYTE now */
+        KdStatus = KdpReceiveBuffer(&Byte, sizeof(UCHAR));
+
+        /* Acknowledge the received packet */
+        KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, Packet.PacketId);
+
+//KdpDbgPrint("KdReceivePacket - all ok\n");
+
+        return KDP_PACKET_RECEIVED;
+    }
+
+    return KDP_PACKET_RECEIVED;
+}
+
+
+VOID
+NTAPI
+KdSendPacket(
+    IN ULONG PacketType,
+    IN PSTRING MessageHeader,
+    IN PSTRING MessageData,
+    IN OUT PKD_CONTEXT Context)
+{
+    KD_PACKET Packet;
+    KDP_STATUS KdStatus;
+
+    for (;;)
+    {
+        /* Initialize a KD_PACKET */
+        Packet.PacketLeader = PACKET_LEADER;
+        Packet.PacketType = PacketType;
+        Packet.ByteCount = MessageHeader->Length;
+        Packet.Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
+                                               MessageHeader->Length);
+
+        /* If we have message data, add it to the packet */
+        if (MessageData)
+        {
+            Packet.ByteCount += MessageData->Length;
+            Packet.Checksum += KdpCalculateChecksum(MessageData->Buffer,
+                                                    MessageData->Length);
+        }
+
+        /* Set the packet id */
+        Packet.PacketId = CurrentPacketId;
+
+        /* Send the packet header to the KD port */
+        KdpSendBuffer(&Packet, sizeof(KD_PACKET));
+
+        /* Send the message header */
+        KdpSendBuffer(MessageHeader->Buffer, MessageHeader->Length);
+
+        /* If we have meesage data, also send it */
+        if (MessageData)
+        {
+            KdpSendBuffer(MessageData->Buffer, MessageData->Length);
+        }
+
+        /* Finalize with a trailing byte */
+        KdpSendByte(PACKET_TRAILING_BYTE);
+
+        /* Wait for acknowledge */
+        KdStatus = KdReceivePacket(PACKET_TYPE_KD_ACKNOWLEDGE,
+                                  NULL,
+                                  NULL,
+                                  0,
+                                  NULL);
+
+        /* Did we succeed? */
+        if (KdStatus == KDP_PACKET_RECEIVED)
+        {
+            CurrentPacketId &= ~SYNC_PACKET_ID;
+            break;
+        }
+
+        /* PACKET_TYPE_KD_DEBUG_IO is allowed to instantly timeout */
+        if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
+        {
+            /* No response, silently fail. */
+//            return;
+        }
+
+        /* Packet timed out, send it again */
+    }
+
+    return;
+}
+

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,33 @@
+/*
+ * COPYRIGHT:       GPL, see COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/base/kddll/kddll.h
+ * PURPOSE:         Base definitions for the kernel debugger.
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer at ewactos.org)
+ */
+
+#define NOEXTAPI
+#include <ntddk.h>
+#define NDEBUG
+#include <halfuncs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <debug.h>
+#include "arc/arc.h"
+#include "windbgkd.h"
+
+#include <wdbgexts.h>
+#include <ioaccess.h> /* port intrinsics */
+
+typedef UCHAR BYTE, *PBYTE;
+
+typedef ULONG (*DBGRNT)(const char *Format, ...);
+extern DBGRNT KdpDbgPrint;
+
+typedef enum
+{
+    KDP_PACKET_RECEIVED = 0,
+    KDP_PACKET_TIMEOUT = 1,
+    KDP_PACKET_RESEND = 2
+} KDP_STATUS;
+

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,23 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+
+<module name="kdlib" type="staticlibrary">
+	<include base="kdlib">.</include>
+	<library>ntoskrnl</library>
+	<library>hal</library>
+	<file>kddll.c</file>
+</module>
+
+<module name="kdserial" type="staticlibrary">
+	<include base="kdserial">.</include>
+	<file>kdserial.c</file>
+</module>
+
+<module name="kdcom" type="kernelmodedll" entrypoint="0" installbase="system32" installname="kdcom.dll">
+	<importlibrary definition="kddll.spec"></importlibrary>
+	<bootstrap installbase="$(CDOUTPUT)" nameoncd="kdcom.dll" />
+	<include base="kdcom">.</include>
+	<library>kdlib</library>
+	<library>kdserial</library>
+	<file>kdcom.c</file>
+</module>

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,8 @@
+@ stdcall KdD0Transition()
+@ stdcall KdD3Transition()
+@ stdcall KdDebuggerInitialize0(ptr)
+@ stdcall KdDebuggerInitialize1(ptr)
+@ stdcall KdReceivePacket(long ptr ptr ptr ptr)
+@ stdcall KdRestore(long)
+@ stdcall KdSave(long)
+@ stdcall KdSendPacket(long ptr ptr ptr)

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kddll.spec
------------------------------------------------------------------------------
    svn:eol-style = native

Added: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c
URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c?rev=43674&view=auto
==============================================================================
--- branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c (added)
+++ branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c [iso-8859-1] Wed Oct 21 22:03:27 2009
@@ -1,0 +1,145 @@
+/*
+ * COPYRIGHT:       GPL, see COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            drivers/base/kddll/kdserial.c
+ * PURPOSE:         Serial communication functions for the kernel debugger.
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer at ewactos.org)
+ */
+
+#include "kddll.h"
+
+
+
+/******************************************************************************
+ * \name KdpSendBuffer
+ * \brief Sends a buffer of data to the serial KD port.
+ * \param Buffer Pointer to the data.
+ * \param Size Size of data in bytes.
+ */
+VOID
+NTAPI
+KdpSendBuffer(
+    IN PVOID Buffer,
+    IN ULONG Size)
+{
+    INT i;
+    for (i = 0; i < Size; i++)
+    {
+        KdpSendByte(((PUCHAR)Buffer)[i]);
+    }
+}
+
+/******************************************************************************
+ * \name KdpReceiveBuffer
+ * \brief Recieves data from the KD port and fills a buffer.
+ * \param Buffer Pointer to a buffer that receives the data.
+ * \param Size Size of data to receive in bytes.
+ * \return KDP_PACKET_RECEIVED if successful. 
+ *         KDP_PACKET_TIMEOUT if the receice timed out.
+ */
+KDP_STATUS
+NTAPI
+KdpReceiveBuffer(
+    OUT PVOID Buffer,
+    IN  ULONG Size)
+{
+    ULONG i;
+    PUCHAR ByteBuffer = Buffer;
+    KDP_STATUS Status;
+
+    for (i = 0; i < Size; i++)
+    {
+        /* Try to get a byte from the port */
+        Status = KdpReceiveByte(&ByteBuffer[i]);
+
+        if (Status != KDP_PACKET_RECEIVED)
+        {
+            return Status;
+        }
+    }
+
+    return KDP_PACKET_RECEIVED;
+}
+
+
+/******************************************************************************
+ * \name KdpReceivePacketLeader
+ * \brief Recieves a packet leadr from the KD port.
+ * \param PacketLeader Pointer to an ULONG that receives the packet leader.
+ * \return KDP_PACKET_RECEIVED if successful. 
+ *         KDP_PACKET_TIMEOUT if the receice timed out.
+ */
+KDP_STATUS
+NTAPI
+KdpReceivePacketLeader(
+    OUT PULONG PacketLeader)
+{
+    UCHAR Index = 0, Byte, Buffer[4];
+    KDP_STATUS KdStatus;
+
+    /* Set first character to 0 */
+    Buffer[0] = 0;
+
+KdpDbgPrint("KdpReceivePacketLeader\n" );
+
+    do
+    {
+        /* Receive a single Byte */
+        KdStatus = KdpReceiveByte(&Byte);
+
+        /* Check for timeout */
+        if (KdStatus == KDP_PACKET_TIMEOUT)
+        {
+            /* Report timeout */
+            KdpDbgPrint("KDP_PACKET_TIMEOUT\n");
+            return KDP_PACKET_TIMEOUT;
+        }
+
+        /* Check if we received a byte */
+        if (KdStatus == KDP_PACKET_RECEIVED)
+        {
+            /* Check for breakin byte */
+            if (Byte == BREAKIN_PACKET_BYTE)
+            {
+                KdpDbgPrint("BREAKIN_PACKET_BYTE\n");
+            }
+
+            /* Check if this is a valid packet leader byte */
+            if (Byte == PACKET_LEADER_BYTE ||
+                Byte == CONTROL_PACKET_LEADER_BYTE)
+            {
+                KdpDbgPrint("received byte 0x%x, Index = %d\n", Byte, Index);
+                /* Check if we match the first byte */
+                if (Byte != Buffer[0])
+                {
+                    /* No, this is the new byte 0! */
+                    Index = 0;
+                }
+
+                /* Store the byte in the buffer */
+                Buffer[Index] = Byte;
+
+                /* Continue with next byte */
+                Index++;
+                continue;
+            }
+        }
+
+        /* Restart */
+        Index = 0;
+        Buffer[0] = 0;
+    }
+    while (Index < 4);
+
+    /* Enable the debugger */
+//    KdDebuggerNotPresent = FALSE;
+    SharedUserData->KdDebuggerEnabled |= 0x00000002;
+
+    /* Return the received packet leader */
+    *PacketLeader = *(PULONG)Buffer;
+
+KdpDbgPrint("KDP_PACKET_RECEIVED\n");
+
+    return KDP_PACKET_RECEIVED;
+}
+

Propchange: branches/ros-amd64-bringup/reactos/drivers/base/kddll/kdserial.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list