Author: tkreuzer
Date: Thu Oct 22 16:58:33 2009
New Revision: 43688
URL:
http://svn.reactos.org/svn/reactos?rev=43688&view=rev
Log:
[KDCOM]
- Merge r43682
- Copy new kdcom from amd64 branch. It's only built when _WINKD_ is set to 1 in the
config file.
Happy testing.
Added:
trunk/reactos/drivers/base/kddll/ (with props)
trunk/reactos/drivers/base/kddll/kdcom.c (with props)
trunk/reactos/drivers/base/kddll/kdcom.h (with props)
trunk/reactos/drivers/base/kddll/kddll.c (with props)
trunk/reactos/drivers/base/kddll/kddll.h (with props)
trunk/reactos/drivers/base/kddll/kddll.rbuild (with props)
trunk/reactos/drivers/base/kddll/kddll.spec (with props)
trunk/reactos/drivers/base/kddll/kdserial.c (with props)
Modified:
trunk/reactos/ (props changed)
trunk/reactos/drivers/base/directory.rbuild
trunk/reactos/include/reactos/windbgkd.h
trunk/reactos/ntoskrnl/kd64/kdinit.c
trunk/reactos/ntoskrnl/kd64/kdlock.c
Propchange: trunk/reactos/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Oct 22 16:58:33 2009
@@ -1,1 +1,1 @@
-/branches/ros-amd64-bringup/reactos:34711-34712,34743,34812,34839,34842,34917,35323-35324,35347-35348,35361,35436,35509,35515,35588,35739,35746,35771,35789,35823,35902,35904-35906,35942,35947-35949,35952-35953,35966,36013,36360,36388-36389,36570,36614,36930,37323,37434,37472,37475,37536,37820-37821,37869,37873,37990-37991,38013-38014,38148,38151,38265,38268,39151,39333,39345,40991,41000,41027-41028,41050,41052,41082-41086,41549,43080,43426,43454
+/branches/ros-amd64-bringup/reactos:34711-34712,34743,34812,34839,34842,34917,35323-35324,35347-35348,35361,35436,35509,35515,35588,35739,35746,35771,35789,35823,35902,35904-35906,35942,35947-35949,35952-35953,35966,36013,36360,36388-36389,36570,36614,36930,37323,37434,37472,37475,37536,37820-37821,37868-37869,37873,37990-37991,38013-38014,38148,38151,38265,38268,39151,39333,39345,40991,41000,41027-41028,41030,41050,41052,41082-41086,41499,41549,43080,43426,43454,43677,43682
Modified: trunk/reactos/drivers/base/directory.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/directory.rbu…
==============================================================================
--- trunk/reactos/drivers/base/directory.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/base/directory.rbuild [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -7,9 +7,16 @@
<directory name="bootvid">
<xi:include href="bootvid/bootvid.rbuild" />
</directory>
-<directory name="kdcom">
- <xi:include href="kdcom/kdcom.rbuild" />
-</directory>
+<ifnot property="_WINKD_" value="1">
+ <directory name="kdcom">
+ <xi:include href="kdcom/kdcom.rbuild" />
+ </directory>
+</if>
+<if property="_WINKD_" value="1">
+ <directory name="kddll">
+ <xi:include href="kddll/kddll.rbuild" />
+ </directory>
+</if>
<directory name="null">
<xi:include href="null/null.rbuild" />
</directory>
Propchange: trunk/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Thu Oct 22 16:58:33 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)
Propchange: trunk/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
bugtraq:message = See issue #%BUGID% for more details.
Propchange: trunk/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
bugtraq:url =
http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%
Propchange: trunk/reactos/drivers/base/kddll/
------------------------------------------------------------------------------
tsvn:logminsize = 10
Added: trunk/reactos/drivers/base/kddll/kdcom.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kdcom.c…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kdcom.c (added)
+++ trunk/reactos/drivers/base/kddll/kdcom.c [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -1,0 +1,291 @@
+/*
+ * 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(a)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;
+
+ KDDBGPRINT("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;
+ }
+ }
+ }
+
+ /* 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: trunk/reactos/drivers/base/kddll/kdcom.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kdcom.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kdcom.h…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kdcom.h (added)
+++ trunk/reactos/drivers/base/kddll/kdcom.h [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -1,0 +1,57 @@
+/*
+ * 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(a)ewactos.org)
+ */
+
+#ifndef _KDCOM_H_
+#define _KDCOM_H_
+
+#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 /* 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). */
+
+#endif /* !_KDCOM_H_ */
Propchange: trunk/reactos/drivers/base/kddll/kdcom.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kddll.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kddll.c…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kddll.c (added)
+++ trunk/reactos/drivers/base/kddll/kddll.c [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -1,0 +1,421 @@
+/*
+ * 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(a)ewactos.org)
+ */
+
+//#define KDDEBUG /* uncomment to enable debugging this dll */
+#include "kddll.h"
+
+/* GLOBALS ********************************************************************/
+
+PFNDBGPRNT KdpDbgPrint = NULL;
+ULONG CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
+
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+/******************************************************************************
+ * \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-de…
+ */
+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 FUNCTIONS ***********************************************************/
+
+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;
+ KDDBGPRINT("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 KdContext)
+{
+ 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)
+ {
+ /* Check if we got a breakin */
+ if (KdStatus == KDP_PACKET_RESEND)
+ {
+ KdContext->BreakInRequested = TRUE;
+ }
+ 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:
+ /* Are we waiting for an ACK packet? */
+ if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE &&
+ Packet.PacketId == (CurrentPacketId & ~SYNC_PACKET_ID))
+ {
+ /* 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:
+ KDDBGPRINT("KdReceivePacket - got a reset packet\n");
+ KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
+ CurrentPacketId = INITIAL_PACKET_ID;
+ /* Fall through */
+
+ case PACKET_TYPE_KD_RESEND:
+ KDDBGPRINT("KdReceivePacket - got
PACKET_TYPE_KD_RESEND\n");
+ /* Remote wants us to resend the last packet */
+ return KDP_PACKET_RESEND;
+
+ default:
+ KDDBGPRINT("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 */
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ CurrentPacketId ^= 1;
+ return KDP_PACKET_RECEIVED;
+ }
+
+ /* Did we get the right packet type? */
+ if (PacketType != Packet.PacketType)
+ {
+ /* We received something different, start over */
+ KDDBGPRINT("KdReceivePacket - wrong PacketType\n");
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ 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:
+ KDDBGPRINT("KdReceivePacket - unknown PacketType\n");
+ return KDP_PACKET_RESEND;
+ }
+
+ //KDDBGPRINT("KdReceivePacket - got normal PacketType\n");
+
+ /* Packet smaller than expected? */
+ if (MessageHeader->Length > Packet.ByteCount)
+ {
+ KDDBGPRINT("KdReceivePacket - too few data (%d) for type %d\n",
+ Packet.ByteCount, MessageHeader->Length);
+ MessageHeader->Length = Packet.ByteCount;
+ }
+
+ //KDDBGPRINT("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. Packet needs to be resent. */
+ KDDBGPRINT("KdReceivePacket - Didn't receive message header
data.\n");
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ continue;
+ }
+
+ //KDDBGPRINT("KdReceivePacket - got normal PacketType 3\n");
+
+ /* Calculate checksum for the header data */
+ Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
+ MessageHeader->Length);
+
+ /* Calculate the length of the message data */
+ *DataLength = Packet.ByteCount - MessageHeader->Length;
+
+ /* Shall we receive messsage data? */
+ if (MessageData)
+ {
+ /* Set the length of the message data */
+ MessageData->Length = *DataLength;
+
+ /* Do we have data? */
+ if (MessageData->Length)
+ {
+ KDDBGPRINT("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. */
+ KDDBGPRINT("KdReceivePacket - Didn't receive message
data.\n");
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ continue;
+ }
+
+ /* Add cheksum for message data */
+ Checksum += KdpCalculateChecksum(MessageData->Buffer,
+ MessageData->Length);
+ }
+ }
+
+ /* Compare checksum */
+ if (Packet.Checksum != Checksum)
+ {
+ KDDBGPRINT("KdReceivePacket - wrong cheksum, got %x, calculated
%x\n",
+ Packet.Checksum, Checksum);
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ continue;
+ }
+
+ /* We must receive a PACKET_TRAILING_BYTE now */
+ KdStatus = KdpReceiveBuffer(&Byte, sizeof(UCHAR));
+ if (KdStatus != KDP_PACKET_RECEIVED || Byte != PACKET_TRAILING_BYTE)
+ {
+ KDDBGPRINT("KdReceivePacket - wrong trailing byte (0x%x), status
0x%x\n", Byte, KdStatus);
+ KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
+ continue;
+ }
+
+ /* Acknowledge the received packet */
+ KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, Packet.PacketId);
+
+ //KDDBGPRINT("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;
+
+ /* 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);
+ }
+
+ for (;;)
+ {
+ /* 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: trunk/reactos/drivers/base/kddll/kddll.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kddll.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kddll.h…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kddll.h (added)
+++ trunk/reactos/drivers/base/kddll/kddll.h [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -1,0 +1,85 @@
+/*
+ * 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(a)ewactos.org)
+ */
+
+#ifndef _KDDLL_H_
+#define _KDDLL_H_
+
+#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 (*PFNDBGPRNT)(const char *Format, ...);
+extern PFNDBGPRNT KdpDbgPrint;
+
+typedef enum
+{
+ KDP_PACKET_RECEIVED = 0,
+ KDP_PACKET_TIMEOUT = 1,
+ KDP_PACKET_RESEND = 2
+} KDP_STATUS;
+
+#ifndef KDDEBUG
+#define KDDBGPRINT(...)
+#else
+#define KDDBGPRINT KdpDbgPrint
+#endif
+
+VOID
+NTAPI
+KdpSendBuffer(
+ IN PVOID Buffer,
+ IN ULONG Size);
+
+KDP_STATUS
+NTAPI
+KdpReceiveBuffer(
+ OUT PVOID Buffer,
+ IN ULONG Size);
+
+KDP_STATUS
+NTAPI
+KdpReceivePacketLeader(
+ OUT PULONG PacketLeader);
+
+VOID
+NTAPI
+KdpSendByte(IN BYTE Byte);
+
+KDP_STATUS
+NTAPI
+KdpPollByte(OUT PBYTE OutByte);
+
+KDP_STATUS
+NTAPI
+KdpReceiveByte(OUT PBYTE OutByte);
+
+KDP_STATUS
+NTAPI
+KdpPollBreakIn();
+
+
+#if 0
+NTSTATUS
+NTAPI
+KdDebuggerInitialize0(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL);
+#endif
+
+
+#endif /* !_KDDLL_H_ */
Propchange: trunk/reactos/drivers/base/kddll/kddll.h
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kddll.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kddll.r…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kddll.rbuild (added)
+++ trunk/reactos/drivers/base/kddll/kddll.rbuild [iso-8859-1] Thu Oct 22 16:58:33 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: trunk/reactos/drivers/base/kddll/kddll.rbuild
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kddll.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kddll.s…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kddll.spec (added)
+++ trunk/reactos/drivers/base/kddll/kddll.spec [iso-8859-1] Thu Oct 22 16:58:33 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: trunk/reactos/drivers/base/kddll/kddll.spec
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/base/kddll/kdserial.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kddll/kdseria…
==============================================================================
--- trunk/reactos/drivers/base/kddll/kdserial.c (added)
+++ trunk/reactos/drivers/base/kddll/kdserial.c [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -1,0 +1,149 @@
+/*
+ * 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(a)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 receive timed out.
+ * KDP_PACKET_RESEND if a breakin byte was detected.
+ */
+KDP_STATUS
+NTAPI
+KdpReceivePacketLeader(
+ OUT PULONG PacketLeader)
+{
+ UCHAR Index = 0, Byte, Buffer[4];
+ KDP_STATUS KdStatus;
+
+ /* Set first character to 0 */
+ Buffer[0] = 0;
+
+ do
+ {
+ /* Receive a single byte */
+ KdStatus = KdpReceiveByte(&Byte);
+
+ /* Check for timeout */
+ if (KdStatus == KDP_PACKET_TIMEOUT)
+ {
+ /* Check if we already got a breakin byte */
+ if (Buffer[0] == BREAKIN_PACKET_BYTE)
+ {
+ return KDP_PACKET_RESEND;
+ }
+
+ /* Report timeout */
+ return KDP_PACKET_TIMEOUT;
+ }
+
+ /* Check if we received a byte */
+ if (KdStatus == KDP_PACKET_RECEIVED)
+ {
+ /* Check if this is a valid packet leader byte */
+ if (Byte == PACKET_LEADER_BYTE ||
+ Byte == CONTROL_PACKET_LEADER_BYTE)
+ {
+ /* 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;
+ }
+
+ /* Check for breakin byte */
+ if (Byte == BREAKIN_PACKET_BYTE)
+ {
+ KdpDbgPrint("BREAKIN_PACKET_BYTE\n");
+ Index = 0;
+ Buffer[0] = Byte;
+ 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;
+
+ return KDP_PACKET_RECEIVED;
+}
+
Propchange: trunk/reactos/drivers/base/kddll/kdserial.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/include/reactos/windbgkd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/windbgkd.h…
==============================================================================
--- trunk/reactos/include/reactos/windbgkd.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/windbgkd.h [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -211,8 +211,8 @@
//
typedef struct _KD_CONTEXT
{
- ULONG KdpDefaultRetries;
- BOOLEAN KdpControlCPending;
+ ULONG RetryCount;
+ BOOLEAN BreakInRequested;
} KD_CONTEXT, *PKD_CONTEXT;
//
Modified: trunk/reactos/ntoskrnl/kd64/kdinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdinit.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdinit.c [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -284,7 +284,7 @@
if (!KdpDebuggerStructuresInitialized)
{
/* Set the Debug Switch Routine and Retries*/
- KdpContext.KdpDefaultRetries = 20;
+ KdpContext.RetryCount = 20;
KiDebugSwitchRoutine = KdpSwitchProcessor;
/* Initialize the Time Slip DPC */
Modified: trunk/reactos/ntoskrnl/kd64/kdlock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kd64/kdlock.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/kd64/kdlock.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/kd64/kdlock.c [iso-8859-1] Thu Oct 22 16:58:33 2009
@@ -40,11 +40,11 @@
if (KdDebuggerEnabled)
{
/* Check if a CTRL-C is in the queue */
- if (KdpContext.KdpControlCPending)
+ if (KdpContext.BreakInRequested)
{
/* Set it and prepare for break */
DoBreak = TRUE;
- KdpContext.KdpControlCPending = FALSE;
+ KdpContext.BreakInRequested = FALSE;
}
else
{
@@ -83,12 +83,12 @@
Enable = KeDisableInterrupts();
/* Check if a CTRL-C is in the queue */
- if (KdpContext.KdpControlCPending)
+ if (KdpContext.BreakInRequested)
{
/* Set it and prepare for break */
KdpControlCPressed = TRUE;
DoBreak = TRUE;
- KdpContext.KdpControlCPending = FALSE;
+ KdpContext.BreakInRequested = FALSE;
}
else
{