mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 05:43:08 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
21
drivers/base/kdcom/CMakeLists.txt
Normal file
21
drivers/base/kdcom/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
spec2def(kdcom.dll kdcom.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
kdcom.c
|
||||
kddll.c
|
||||
kdserial.c
|
||||
kddll.h)
|
||||
|
||||
add_library(kdcom SHARED
|
||||
${SOURCE}
|
||||
kdcom.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdcom.def)
|
||||
|
||||
set_module_type(kdcom module IMAGEBASE 0x00010000)
|
||||
set_subsystem(kdcom native)
|
||||
add_importlibs(kdcom ntoskrnl hal)
|
||||
target_link_libraries(kdcom cportlib)
|
||||
add_dependencies(kdcom psdk bugcodes)
|
||||
add_pch(kdcom kddll.h SOURCE)
|
||||
add_cd_file(TARGET kdcom DESTINATION reactos/system32 NO_CAB FOR all)
|
267
drivers/base/kdcom/arm/kdbg.c
Normal file
267
drivers/base/kdcom/arm/kdbg.c
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/base/kdcom/arm/kdbg.c
|
||||
* PURPOSE: Serial Port Kernel Debugging Transport Library
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#define NOEXTAPI
|
||||
#include <ntifs.h>
|
||||
#define NDEBUG
|
||||
#include <halfuncs.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include "arc/arc.h"
|
||||
#include "windbgkd.h"
|
||||
#include <kddll.h>
|
||||
#include <ioaccess.h>
|
||||
#include <arm/peripherals/pl011.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
typedef struct _KD_PORT_INFORMATION
|
||||
{
|
||||
ULONG ComPort;
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
||||
|
||||
KD_PORT_INFORMATION DefaultPort = {0, 0, 0};
|
||||
|
||||
//
|
||||
// We need to build this in the configuration root and use KeFindConfigurationEntry
|
||||
// to recover it later.
|
||||
//
|
||||
#define HACK 24000000
|
||||
|
||||
/* REACTOS FUNCTIONS **********************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN ULONG Unknown1,
|
||||
IN ULONG Unknown2)
|
||||
{
|
||||
ULONG Divider, Remainder, Fraction;
|
||||
ULONG Baudrate = PortInformation->BaudRate;
|
||||
|
||||
//
|
||||
// Calculate baudrate clock divider and remainder
|
||||
//
|
||||
Divider = HACK / (16 * Baudrate);
|
||||
Remainder = HACK % (16 * Baudrate);
|
||||
|
||||
//
|
||||
// Calculate the fractional part
|
||||
//
|
||||
Fraction = (8 * Remainder / Baudrate) >> 1;
|
||||
Fraction += (8 * Remainder / Baudrate) & 1;
|
||||
|
||||
//
|
||||
// Disable interrupts
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_CR, 0);
|
||||
|
||||
//
|
||||
// Set the baud rate
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_IBRD, Divider);
|
||||
WRITE_REGISTER_ULONG(UART_PL011_FBRD, Fraction);
|
||||
|
||||
//
|
||||
// Set 8 bits for data, 1 stop bit, no parity, FIFO enabled
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_LCRH,
|
||||
UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN);
|
||||
|
||||
//
|
||||
// Clear and enable FIFO
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL011_CR,
|
||||
UART_PL011_CR_UARTEN |
|
||||
UART_PL011_CR_TXE |
|
||||
UART_PL011_CR_RXE);
|
||||
|
||||
//
|
||||
// Done
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitialize(IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN ULONG Unknown1,
|
||||
IN ULONG Unknown2)
|
||||
{
|
||||
//
|
||||
// Call the extended version
|
||||
//
|
||||
return KdPortInitializeEx(PortInformation, Unknown1, Unknown2);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByte(OUT PUCHAR ByteReceived)
|
||||
{
|
||||
//
|
||||
// Call the extended version
|
||||
//
|
||||
return KdPortGetByteEx(&DefaultPort, ByteReceived);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortPollByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortPollByte(OUT PUCHAR ByteReceived)
|
||||
{
|
||||
//
|
||||
// Call the extended version
|
||||
//
|
||||
return KdPortPollByteEx(&DefaultPort, ByteReceived);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN UCHAR ByteToSend)
|
||||
{
|
||||
//
|
||||
// Wait for ready
|
||||
//
|
||||
while ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_TXFF) != 0);
|
||||
|
||||
//
|
||||
// Send the character
|
||||
//
|
||||
WRITE_REGISTER_ULONG(UART_PL01x_DR, ByteToSend);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByte(IN UCHAR ByteToSend)
|
||||
{
|
||||
//
|
||||
// Call the extended version
|
||||
//
|
||||
KdPortPutByteEx(&DefaultPort, ByteToSend);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortRestore(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortSave(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortDisableInterrupts(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortEnableInterrupts(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* WINDOWS FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdSave(IN BOOLEAN SleepTransition)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdRestore(IN BOOLEAN SleepTransition)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdSendPacket(IN ULONG PacketType,
|
||||
IN PSTRING MessageHeader,
|
||||
IN PSTRING MessageData,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdReceivePacket(IN ULONG PacketType,
|
||||
OUT PSTRING MessageHeader,
|
||||
OUT PSTRING MessageData,
|
||||
OUT PULONG DataLength,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
while (TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
499
drivers/base/kdcom/i386/kdbg.c
Normal file
499
drivers/base/kdcom/i386/kdbg.c
Normal file
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: drivers/base/kdcom/kdbg.c
|
||||
* PURPOSE: Serial i/o functions for the kernel debugger.
|
||||
* PROGRAMMER: Alex Ionescu
|
||||
* Hervé Poussineau
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#define NOEXTAPI
|
||||
#include <ntifs.h>
|
||||
#include <halfuncs.h>
|
||||
#include <stdio.h>
|
||||
#include "arc/arc.h"
|
||||
#include "windbgkd.h"
|
||||
#include <kddll.h>
|
||||
#include <ioaccess.h> /* port intrinsics */
|
||||
#include <cportlib/cportlib.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
typedef struct _KD_PORT_INFORMATION
|
||||
{
|
||||
ULONG ComPort;
|
||||
ULONG BaudRate;
|
||||
ULONG BaseAddress;
|
||||
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN ULONG Unknown1,
|
||||
IN ULONG Unknown2);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortPollByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN UCHAR ByteToSend);
|
||||
|
||||
#define DEFAULT_BAUD_RATE 19200
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
const ULONG BaseArray[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||
#elif defined(_M_PPC)
|
||||
const ULONG BaseArray[] = {0, 0x800003F8};
|
||||
#elif defined(_M_MIPS)
|
||||
const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
|
||||
#elif defined(_M_ARM)
|
||||
const ULONG BaseArray[] = {0, 0xF1012000};
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
/* MACROS *******************************************************************/
|
||||
|
||||
#define SER_RBR(x) ((PUCHAR)(x)+0)
|
||||
#define SER_THR(x) ((PUCHAR)(x)+0)
|
||||
#define SER_DLL(x) ((PUCHAR)(x)+0)
|
||||
#define SER_IER(x) ((PUCHAR)(x)+1)
|
||||
#define SR_IER_ERDA 0x01
|
||||
#define SR_IER_ETHRE 0x02
|
||||
#define SR_IER_ERLSI 0x04
|
||||
#define SR_IER_EMS 0x08
|
||||
#define SR_IER_ALL 0x0F
|
||||
#define SER_DLM(x) ((PUCHAR)(x)+1)
|
||||
#define SER_IIR(x) ((PUCHAR)(x)+2)
|
||||
#define SER_FCR(x) ((PUCHAR)(x)+2)
|
||||
#define SR_FCR_ENABLE_FIFO 0x01
|
||||
#define SR_FCR_CLEAR_RCVR 0x02
|
||||
#define SR_FCR_CLEAR_XMIT 0x04
|
||||
#define SER_LCR(x) ((PUCHAR)(x)+3)
|
||||
#define SR_LCR_CS5 0x00
|
||||
#define SR_LCR_CS6 0x01
|
||||
#define SR_LCR_CS7 0x02
|
||||
#define SR_LCR_CS8 0x03
|
||||
#define SR_LCR_ST1 0x00
|
||||
#define SR_LCR_ST2 0x04
|
||||
#define SR_LCR_PNO 0x00
|
||||
#define SR_LCR_POD 0x08
|
||||
#define SR_LCR_PEV 0x18
|
||||
#define SR_LCR_PMK 0x28
|
||||
#define SR_LCR_PSP 0x38
|
||||
#define SR_LCR_BRK 0x40
|
||||
#define SR_LCR_DLAB 0x80
|
||||
#define SER_MCR(x) ((PUCHAR)(x)+4)
|
||||
#define SR_MCR_DTR 0x01
|
||||
#define SR_MCR_RTS 0x02
|
||||
#define SR_MCR_OUT1 0x04
|
||||
#define SR_MCR_OUT2 0x08
|
||||
#define SR_MCR_LOOP 0x10
|
||||
#define SER_LSR(x) ((PUCHAR)(x)+5)
|
||||
#define SR_LSR_DR 0x01
|
||||
#define SR_LSR_TBE 0x20
|
||||
#define SER_MSR(x) ((PUCHAR)(x)+6)
|
||||
#define SR_MSR_CTS 0x10
|
||||
#define SR_MSR_DSR 0x20
|
||||
#define SER_SCR(x) ((PUCHAR)(x)+7)
|
||||
|
||||
|
||||
/* GLOBAL VARIABLES *********************************************************/
|
||||
|
||||
/* STATIC VARIABLES *********************************************************/
|
||||
|
||||
static KD_PORT_INFORMATION DefaultPort = { 0, 0, 0 };
|
||||
|
||||
/* The com port must only be initialized once! */
|
||||
static BOOLEAN PortInitialized = FALSE;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/* HAL.KdPortInitialize */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitialize(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN ULONG Unknown1,
|
||||
IN ULONG Unknown2)
|
||||
{
|
||||
SIZE_T i;
|
||||
CHAR buffer[80];
|
||||
|
||||
if (!PortInitialized)
|
||||
{
|
||||
DefaultPort.BaudRate = PortInformation->BaudRate;
|
||||
|
||||
if (PortInformation->ComPort == 0)
|
||||
{
|
||||
/*
|
||||
* Start enumerating COM ports from the last one to the first one,
|
||||
* and break when we find a valid port.
|
||||
* If we reach the first element of the list, the invalid COM port,
|
||||
* then it means that no valid port was found.
|
||||
*/
|
||||
for (i = sizeof(BaseArray) / sizeof(BaseArray[0]) - 1; i > 0; i--)
|
||||
{
|
||||
if (CpDoesPortExist(UlongToPtr(BaseArray[i])))
|
||||
{
|
||||
PortInformation->BaseAddress = DefaultPort.BaseAddress = BaseArray[i];
|
||||
PortInformation->ComPort = DefaultPort.ComPort = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: No COM port found!\n\n");
|
||||
HalDisplayString(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PortInitialized = TRUE;
|
||||
}
|
||||
|
||||
/* initialize port */
|
||||
if (!KdPortInitializeEx(&DefaultPort, Unknown1, Unknown2))
|
||||
return FALSE;
|
||||
|
||||
/* set global info */
|
||||
KdComPortInUse = (PUCHAR)DefaultPort.BaseAddress;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortInitializeEx ; ReactOS-specific */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortInitializeEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN ULONG Unknown1,
|
||||
IN ULONG Unknown2)
|
||||
{
|
||||
ULONG ComPortBase;
|
||||
CHAR buffer[80];
|
||||
ULONG divisor;
|
||||
UCHAR lcr;
|
||||
|
||||
#ifdef _ARM_
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (PortInformation->BaudRate == 0)
|
||||
PortInformation->BaudRate = DEFAULT_BAUD_RATE;
|
||||
|
||||
if (PortInformation->ComPort != 0)
|
||||
{
|
||||
if (!CpDoesPortExist(UlongToPtr(BaseArray[PortInformation->ComPort])))
|
||||
{
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: Serial port not found!\n\n");
|
||||
HalDisplayString(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ComPortBase = BaseArray[PortInformation->ComPort];
|
||||
PortInformation->BaseAddress = ComPortBase;
|
||||
}
|
||||
else
|
||||
{
|
||||
ComPortBase = PortInformation->BaseAddress;
|
||||
}
|
||||
|
||||
if (ComPortBase == 0)
|
||||
return FALSE;
|
||||
|
||||
#ifndef NDEBUG
|
||||
sprintf(buffer,
|
||||
"\nSerial port COM%ld found at 0x%lx\n",
|
||||
PortInformation->ComPort,
|
||||
ComPortBase);
|
||||
HalDisplayString(buffer);
|
||||
#endif /* NDEBUG */
|
||||
|
||||
/* set baud rate and data format (8N1) */
|
||||
|
||||
/* turn on DTR and RTS */
|
||||
WRITE_PORT_UCHAR(SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
|
||||
|
||||
/* set DLAB */
|
||||
lcr = READ_PORT_UCHAR(SER_LCR(ComPortBase)) | SR_LCR_DLAB;
|
||||
WRITE_PORT_UCHAR(SER_LCR(ComPortBase), lcr);
|
||||
|
||||
/* set baud rate */
|
||||
divisor = 115200 / PortInformation->BaudRate;
|
||||
WRITE_PORT_UCHAR(SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
|
||||
WRITE_PORT_UCHAR(SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
|
||||
|
||||
/* reset DLAB and set 8N1 format */
|
||||
WRITE_PORT_UCHAR(SER_LCR(ComPortBase),
|
||||
SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
|
||||
|
||||
/* read junk out of the RBR */
|
||||
lcr = READ_PORT_UCHAR(SER_RBR(ComPortBase));
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* print message to blue screen */
|
||||
sprintf(buffer,
|
||||
"\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
|
||||
PortInformation->ComPort,
|
||||
ComPortBase,
|
||||
PortInformation->BaudRate);
|
||||
|
||||
HalDisplayString(buffer);
|
||||
#endif /* NDEBUG */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortGetByte */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByte(
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
if (!PortInitialized)
|
||||
return FALSE;
|
||||
return KdPortGetByteEx(&DefaultPort, ByteReceived);
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortGetByteEx ; ReactOS-specific */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortGetByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
|
||||
|
||||
if ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR))
|
||||
{
|
||||
*ByteReceived = READ_PORT_UCHAR(SER_RBR(ComPortBase));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortPollByte */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortPollByte(
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
if (!PortInitialized)
|
||||
return FALSE;
|
||||
return KdPortPollByteEx(&DefaultPort, ByteReceived);
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortPollByteEx ; ReactOS-specific */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortPollByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
OUT PUCHAR ByteReceived)
|
||||
{
|
||||
PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
|
||||
|
||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
|
||||
;
|
||||
|
||||
*ByteReceived = READ_PORT_UCHAR(SER_RBR(ComPortBase));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortPutByte */
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByte(
|
||||
IN UCHAR ByteToSend)
|
||||
{
|
||||
if (!PortInitialized)
|
||||
return;
|
||||
KdPortPutByteEx(&DefaultPort, ByteToSend);
|
||||
}
|
||||
|
||||
/* HAL.KdPortPutByteEx ; ReactOS-specific */
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortPutByteEx(
|
||||
IN PKD_PORT_INFORMATION PortInformation,
|
||||
IN UCHAR ByteToSend)
|
||||
{
|
||||
PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
|
||||
|
||||
while ((READ_PORT_UCHAR(SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
|
||||
;
|
||||
|
||||
WRITE_PORT_UCHAR(SER_THR(ComPortBase), ByteToSend);
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortRestore */
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortRestore(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortSave */
|
||||
VOID
|
||||
NTAPI
|
||||
KdPortSave(VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortDisableInterrupts */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortDisableInterrupts(VOID)
|
||||
{
|
||||
UCHAR ch;
|
||||
|
||||
if (!PortInitialized)
|
||||
return FALSE;
|
||||
|
||||
ch = READ_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress));
|
||||
ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
|
||||
WRITE_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress), ch);
|
||||
|
||||
ch = READ_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress));
|
||||
ch &= (~SR_IER_ALL);
|
||||
WRITE_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress), ch);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* HAL.KdPortEnableInterrupts */
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdPortEnableInterrupts(VOID)
|
||||
{
|
||||
UCHAR ch;
|
||||
|
||||
if (PortInitialized == FALSE)
|
||||
return FALSE;
|
||||
|
||||
ch = READ_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress));
|
||||
ch &= (~SR_IER_ALL);
|
||||
ch |= SR_IER_ERDA;
|
||||
WRITE_PORT_UCHAR(SER_IER(DefaultPort.BaseAddress), ch);
|
||||
|
||||
ch = READ_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress));
|
||||
ch &= (~SR_MCR_LOOP);
|
||||
ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
|
||||
WRITE_PORT_UCHAR(SER_MCR(DefaultPort.BaseAddress), ch);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize0(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdSave(
|
||||
IN BOOLEAN SleepTransition)
|
||||
{
|
||||
/* Nothing to do on COM ports */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdRestore(
|
||||
IN BOOLEAN SleepTransition)
|
||||
{
|
||||
/* Nothing to do on COM ports */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KdSendPacket(
|
||||
IN ULONG PacketType,
|
||||
IN PSTRING MessageHeader,
|
||||
IN PSTRING MessageData,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdReceivePacket(
|
||||
IN ULONG PacketType,
|
||||
OUT PSTRING MessageHeader,
|
||||
OUT PSTRING MessageData,
|
||||
OUT PULONG DataLength,
|
||||
IN OUT PKD_CONTEXT Context)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
345
drivers/base/kdcom/kdcom.c
Normal file
345
drivers/base/kdcom/kdcom.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* 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@reactos.org)
|
||||
*/
|
||||
|
||||
#include "kddll.h"
|
||||
|
||||
#include <cportlib/cportlib.h>
|
||||
#include <arc/arc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ndk/halfuncs.h>
|
||||
|
||||
/* 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[] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
|
||||
#elif defined(_M_PPC)
|
||||
const ULONG BaseArray[] = {0, 0x800003F8};
|
||||
#elif defined(_M_MIPS)
|
||||
const ULONG BaseArray[] = {0, 0x80006000, 0x80007000};
|
||||
#elif defined(_M_ARM)
|
||||
const ULONG BaseArray[] = {0, 0xF1012000};
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
#define MAX_COM_PORTS (sizeof(BaseArray) / sizeof(BaseArray[0]) - 1)
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
CPPORT KdComPort;
|
||||
ULONG KdComPortIrq = 0; // Not used at the moment.
|
||||
#ifdef KDDEBUG
|
||||
CPPORT KdDebugComPort;
|
||||
#endif
|
||||
|
||||
/* DEBUGGING ******************************************************************/
|
||||
|
||||
#ifdef KDDEBUG
|
||||
ULONG KdpDbgPrint(const char *Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int Length;
|
||||
char* ptr;
|
||||
CHAR Buffer[512];
|
||||
|
||||
va_start(ap, Format);
|
||||
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Check if we went past the buffer */
|
||||
if (Length == -1)
|
||||
{
|
||||
/* Terminate it if we went over-board */
|
||||
Buffer[sizeof(Buffer) - 1] = '\n';
|
||||
|
||||
/* Put maximum */
|
||||
Length = sizeof(Buffer);
|
||||
}
|
||||
|
||||
ptr = Buffer;
|
||||
while (Length--)
|
||||
{
|
||||
if (*ptr == '\n')
|
||||
CpPutByte(&KdDebugComPort, '\r');
|
||||
|
||||
CpPutByte(&KdDebugComPort, *ptr++);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD0Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD3Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdpPortInitialize(IN ULONG ComPortNumber,
|
||||
IN ULONG ComPortBaudRate)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
KDDBGPRINT("KdpPortInitialize, Port = COM%ld\n", ComPortNumber);
|
||||
|
||||
Status = CpInitialize(&KdComPort,
|
||||
UlongToPtr(BaseArray[ComPortNumber]),
|
||||
ComPortBaudRate);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
KdComPortInUse = KdComPort.Address;
|
||||
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)
|
||||
{
|
||||
ULONG ComPortNumber = DEFAULT_DEBUG_PORT;
|
||||
ULONG ComPortBaudRate = DEFAULT_DEBUG_BAUD_RATE;
|
||||
|
||||
PCHAR CommandLine, PortString, BaudString, IrqString;
|
||||
ULONG Value;
|
||||
|
||||
/* Check if we 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;
|
||||
}
|
||||
|
||||
/* Check for a valid Serial Port */
|
||||
PortString += 3;
|
||||
Value = atol(PortString);
|
||||
if (Value >= sizeof(BaseArray) / sizeof(BaseArray[0]))
|
||||
{
|
||||
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) KdComPortIrq = Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KDDEBUG
|
||||
/*
|
||||
* Try to find a free COM port and use it as the KD debugging port.
|
||||
* NOTE: Inspired by reactos/boot/freeldr/freeldr/comm/rs232.c, Rs232PortInitialize(...)
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Start enumerating COM ports from the last one to the first one,
|
||||
* and break when we find a valid port.
|
||||
* If we reach the first element of the list, the invalid COM port,
|
||||
* then it means that no valid port was found.
|
||||
*/
|
||||
ULONG ComPort;
|
||||
for (ComPort = MAX_COM_PORTS; ComPort > 0; ComPort--)
|
||||
{
|
||||
/* Check if the port exist; skip the KD port */
|
||||
if ((ComPort != ComPortNumber) && CpDoesPortExist(UlongToPtr(BaseArray[ComPort])))
|
||||
break;
|
||||
}
|
||||
if (ComPort != 0)
|
||||
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[ComPort]), DEFAULT_BAUD_RATE);
|
||||
}
|
||||
#endif
|
||||
|
||||
KDDBGPRINT("KdDebuggerInitialize0\n");
|
||||
|
||||
/* Initialize the port */
|
||||
return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* \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)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdpSendByte(IN UCHAR Byte)
|
||||
{
|
||||
/* Send the byte */
|
||||
CpPutByte(&KdComPort, Byte);
|
||||
}
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpPollByte(OUT PUCHAR OutByte)
|
||||
{
|
||||
USHORT Status;
|
||||
|
||||
/* Poll the byte */
|
||||
Status = CpGetByte(&KdComPort, OutByte, FALSE, FALSE);
|
||||
switch (Status)
|
||||
{
|
||||
case CP_GET_SUCCESS:
|
||||
return KDP_PACKET_RECEIVED;
|
||||
|
||||
case CP_GET_NODATA:
|
||||
return KDP_PACKET_TIMEOUT;
|
||||
|
||||
case CP_GET_ERROR:
|
||||
default:
|
||||
return KDP_PACKET_RESEND;
|
||||
}
|
||||
}
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpReceiveByte(OUT PUCHAR OutByte)
|
||||
{
|
||||
USHORT Status;
|
||||
|
||||
/* Get the byte */
|
||||
Status = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
|
||||
switch (Status)
|
||||
{
|
||||
case CP_GET_SUCCESS:
|
||||
return KDP_PACKET_RECEIVED;
|
||||
|
||||
case CP_GET_NODATA:
|
||||
return KDP_PACKET_TIMEOUT;
|
||||
|
||||
case CP_GET_ERROR:
|
||||
default:
|
||||
return KDP_PACKET_RESEND;
|
||||
}
|
||||
}
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpPollBreakIn(VOID)
|
||||
{
|
||||
KDP_STATUS KdStatus;
|
||||
UCHAR Byte;
|
||||
|
||||
KdStatus = KdpPollByte(&Byte);
|
||||
if ((KdStatus == KDP_PACKET_RECEIVED) && (Byte == BREAKIN_PACKET_BYTE))
|
||||
{
|
||||
return KDP_PACKET_RECEIVED;
|
||||
}
|
||||
return KDP_PACKET_TIMEOUT;
|
||||
}
|
||||
|
||||
/* EOF */
|
5
drivers/base/kdcom/kdcom.rc
Normal file
5
drivers/base/kdcom/kdcom.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Kernel Debugger COM Extension DLL"
|
||||
#define REACTOS_STR_INTERNAL_NAME "kdcom"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "kdcom.dll"
|
||||
#include <reactos/version.rc>
|
8
drivers/base/kdcom/kdcom.spec
Normal file
8
drivers/base/kdcom/kdcom.spec
Normal file
|
@ -0,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)
|
427
drivers/base/kdcom/kddll.c
Normal file
427
drivers/base/kdcom/kddll.c
Normal file
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
* 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@reactos.org)
|
||||
*/
|
||||
|
||||
#include "kddll.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
ULONG CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
||||
ULONG RemotePacketId = INITIAL_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-debugging.html
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
KdpCalculateChecksum(
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Length)
|
||||
{
|
||||
PUCHAR ByteBuffer = Buffer;
|
||||
ULONG Checksum = 0;
|
||||
|
||||
while (Length-- > 0)
|
||||
{
|
||||
Checksum += (ULONG)*ByteBuffer++;
|
||||
}
|
||||
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 ***********************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* \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->KdpControlCPending = TRUE;
|
||||
}
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 2 - Read PacketType */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT));
|
||||
if (KdStatus != KDP_PACKET_RECEIVED)
|
||||
{
|
||||
/* Didn't receive a PacketType. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Check if we got a resend packet */
|
||||
if (Packet.PacketLeader == CONTROL_PACKET_LEADER &&
|
||||
Packet.PacketType == PACKET_TYPE_KD_RESEND)
|
||||
{
|
||||
return KDP_PACKET_RESEND;
|
||||
}
|
||||
|
||||
/* Step 3 - Read ByteCount */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.ByteCount, sizeof(USHORT));
|
||||
if (KdStatus != KDP_PACKET_RECEIVED)
|
||||
{
|
||||
/* Didn't receive ByteCount. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 4 - Read PacketId */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.PacketId, sizeof(ULONG));
|
||||
if (KdStatus != KDP_PACKET_RECEIVED)
|
||||
{
|
||||
/* Didn't receive PacketId. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
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. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* 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 PACKET_TYPE_KD_RESET\n");
|
||||
CurrentPacketId = INITIAL_PACKET_ID;
|
||||
RemotePacketId = INITIAL_PACKET_ID;
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
|
||||
/* 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");
|
||||
/* We got an invalid packet, ignore it and start over */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Get size of the message header */
|
||||
MessageHeader->Length = MessageHeader->MaximumLength;
|
||||
|
||||
/* Packet smaller than expected or too big? */
|
||||
if (Packet.ByteCount < MessageHeader->Length ||
|
||||
Packet.ByteCount > PACKET_MAX_SIZE)
|
||||
{
|
||||
KDDBGPRINT("KdReceivePacket - too few data (%d) for type %d\n",
|
||||
Packet.ByteCount, MessageHeader->Length);
|
||||
MessageHeader->Length = Packet.ByteCount;
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
//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 message data? */
|
||||
if (MessageData)
|
||||
{
|
||||
/* Set the length of the message data */
|
||||
MessageData->Length = (USHORT)*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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Acknowledge the received packet */
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, Packet.PacketId);
|
||||
|
||||
/* Check if the received PacketId is ok */
|
||||
if (Packet.PacketId != RemotePacketId)
|
||||
{
|
||||
/* Continue with next packet */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Did we get the right packet type? */
|
||||
if (PacketType == Packet.PacketType)
|
||||
{
|
||||
/* Yes, return success */
|
||||
//KDDBGPRINT("KdReceivePacket - all ok\n");
|
||||
RemotePacketId ^= 1;
|
||||
return KDP_PACKET_RECEIVED;
|
||||
}
|
||||
|
||||
/* We received something different, ignore it. */
|
||||
KDDBGPRINT("KdReceivePacket - wrong PacketType\n");
|
||||
}
|
||||
|
||||
return KDP_PACKET_RECEIVED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdSendPacket(
|
||||
IN ULONG PacketType,
|
||||
IN PSTRING MessageHeader,
|
||||
IN PSTRING MessageData,
|
||||
IN OUT PKD_CONTEXT KdContext)
|
||||
{
|
||||
KD_PACKET Packet;
|
||||
KDP_STATUS KdStatus;
|
||||
ULONG Retries;
|
||||
|
||||
/* Initialize a KD_PACKET */
|
||||
Packet.PacketLeader = PACKET_LEADER;
|
||||
Packet.PacketType = (USHORT)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);
|
||||
}
|
||||
|
||||
Retries = KdContext->KdpDefaultRetries;
|
||||
|
||||
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 message 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,
|
||||
NULL,
|
||||
KdContext);
|
||||
|
||||
/* Did we succeed? */
|
||||
if (KdStatus == KDP_PACKET_RECEIVED)
|
||||
{
|
||||
/* Packet received, we can quit the loop */
|
||||
CurrentPacketId &= ~SYNC_PACKET_ID;
|
||||
Retries = KdContext->KdpDefaultRetries;
|
||||
break;
|
||||
}
|
||||
else if (KdStatus == KDP_PACKET_TIMEOUT)
|
||||
{
|
||||
/* Timeout, decrement the retry count */
|
||||
if (Retries > 0)
|
||||
Retries--;
|
||||
|
||||
/*
|
||||
* If the retry count reaches zero, bail out
|
||||
* for packet types allowed to timeout.
|
||||
*/
|
||||
if (Retries == 0)
|
||||
{
|
||||
ULONG MessageId = *(PULONG)MessageHeader->Buffer;
|
||||
switch (PacketType)
|
||||
{
|
||||
case PACKET_TYPE_KD_DEBUG_IO:
|
||||
{
|
||||
if (MessageId != DbgKdPrintStringApi) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_TYPE_KD_STATE_CHANGE32:
|
||||
case PACKET_TYPE_KD_STATE_CHANGE64:
|
||||
{
|
||||
if (MessageId != DbgKdLoadSymbolsStateChange) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_TYPE_KD_FILE_IO:
|
||||
{
|
||||
if (MessageId != DbgKdCreateFileApi) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset debugger state */
|
||||
KD_DEBUGGER_NOT_PRESENT = TRUE;
|
||||
SharedUserData->KdDebuggerEnabled &= ~0x00000002;
|
||||
CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
||||
RemotePacketId = INITIAL_PACKET_ID;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
// else (KdStatus == KDP_PACKET_RESEND) /* Resend the packet */
|
||||
|
||||
/* Packet timed out, send it again */
|
||||
KDDBGPRINT("KdSendPacket got KdStatus 0x%x\n", KdStatus);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
65
drivers/base/kdcom/kddll.h
Normal file
65
drivers/base/kdcom/kddll.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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@reactos.org)
|
||||
*/
|
||||
|
||||
#ifndef _KDDLL_H_
|
||||
#define _KDDLL_H_
|
||||
|
||||
#define NOEXTAPI
|
||||
#include <ntifs.h>
|
||||
#include <windbgkd.h>
|
||||
|
||||
// #define KDDEBUG /* uncomment to enable debugging this dll */
|
||||
|
||||
#ifndef KDDEBUG
|
||||
#define KDDBGPRINT(...)
|
||||
#else
|
||||
extern ULONG KdpDbgPrint(const char* Format, ...);
|
||||
#define KDDBGPRINT KdpDbgPrint
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KDP_PACKET_RECEIVED = 0,
|
||||
KDP_PACKET_TIMEOUT = 1,
|
||||
KDP_PACKET_RESEND = 2
|
||||
} KDP_STATUS;
|
||||
|
||||
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 UCHAR Byte);
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpPollByte(OUT PUCHAR OutByte);
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpReceiveByte(OUT PUCHAR OutByte);
|
||||
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpPollBreakIn(VOID);
|
||||
|
||||
#endif /* _KDDLL_H_ */
|
150
drivers/base/kdcom/kdserial.c
Normal file
150
drivers/base/kdcom/kdserial.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* 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@reactos.org)
|
||||
*/
|
||||
|
||||
#include "kddll.h"
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* \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)
|
||||
{
|
||||
PUCHAR ByteBuffer = Buffer;
|
||||
|
||||
while (Size-- > 0)
|
||||
{
|
||||
KdpSendByte(*ByteBuffer++);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* \name KdpReceiveBuffer
|
||||
* \brief Receives 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 receive timed out.
|
||||
*/
|
||||
KDP_STATUS
|
||||
NTAPI
|
||||
KdpReceiveBuffer(
|
||||
OUT PVOID Buffer,
|
||||
IN ULONG Size)
|
||||
{
|
||||
PUCHAR ByteBuffer = Buffer;
|
||||
UCHAR Byte;
|
||||
KDP_STATUS Status;
|
||||
|
||||
while (Size-- > 0)
|
||||
{
|
||||
/* Try to get a byte from the port */
|
||||
Status = KdpReceiveByte(&Byte);
|
||||
if (Status != KDP_PACKET_RECEIVED)
|
||||
return Status;
|
||||
|
||||
*ByteBuffer++ = Byte;
|
||||
}
|
||||
|
||||
return KDP_PACKET_RECEIVED;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* \name KdpReceivePacketLeader
|
||||
* \brief Receives a packet leader 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)
|
||||
{
|
||||
KDDBGPRINT("BREAKIN_PACKET_BYTE\n");
|
||||
Index = 0;
|
||||
Buffer[0] = Byte;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restart */
|
||||
Index = 0;
|
||||
Buffer[0] = 0;
|
||||
}
|
||||
while (Index < 4);
|
||||
|
||||
/* Enable the debugger */
|
||||
KD_DEBUGGER_NOT_PRESENT = FALSE;
|
||||
SharedUserData->KdDebuggerEnabled |= 0x00000002;
|
||||
|
||||
/* Return the received packet leader */
|
||||
*PacketLeader = *(PULONG)Buffer;
|
||||
|
||||
return KDP_PACKET_RECEIVED;
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue