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/driver... ============================================================================== --- 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/driver... ============================================================================== --- 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@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/driver... ============================================================================== --- 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@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/driver... ============================================================================== --- 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@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-deb... + */ +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/driver... ============================================================================== --- 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@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/driver... ============================================================================== --- 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/driver... ============================================================================== --- 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/driver... ============================================================================== --- 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@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