📄 kdbg.c
字号:
/* $Id: kdbg.c 23670 2006-08-23 17:28:39Z ion $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/kdbg.c
* PURPOSE: Serial i/o functions for the kernel debugger.
* PROGRAMMER: Emanuele Aliberti
* Eric Kohl
* UPDATE HISTORY:
* Created 05/09/99
*/
/* INCLUDES *****************************************************************/
#define NOEXTAPI
#include <ntddk.h>
#define NDEBUG
#include <halfuncs.h>
#include <stdio.h>
#include <debug.h>
#include "arc/arc.h"
#include "windbgkd.h"
typedef struct _KD_PORT_INFORMATION
{
ULONG ComPort;
ULONG BaudRate;
ULONG BaseAddress;
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
#define DEFAULT_BAUD_RATE 19200
/* MACROS *******************************************************************/
#define SER_RBR(x) ((x)+0)
#define SER_THR(x) ((x)+0)
#define SER_DLL(x) ((x)+0)
#define SER_IER(x) ((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) ((x)+1)
#define SER_IIR(x) ((x)+2)
#define SER_FCR(x) ((x)+2)
#define SR_FCR_ENABLE_FIFO 0x01
#define SR_FCR_CLEAR_RCVR 0x02
#define SR_FCR_CLEAR_XMIT 0x04
#define SER_LCR(x) ((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) ((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) ((x)+5)
#define SR_LSR_DR 0x01
#define SR_LSR_TBE 0x20
#define SER_MSR(x) ((x)+6)
#define SR_MSR_CTS 0x10
#define SR_MSR_DSR 0x20
#define SER_SCR(x) ((x)+7)
/* GLOBAL VARIABLES *********************************************************/
/* STATIC VARIABLES *********************************************************/
static ULONG ComPort = 0;
static ULONG BaudRate = 0;
static PUCHAR PortBase = (PUCHAR)0;
/* The com port must only be initialized once! */
static BOOLEAN PortInitialized = FALSE;
/* STATIC FUNCTIONS *********************************************************/
static BOOLEAN
KdpDoesComPortExist (PUCHAR BaseAddress)
{
BOOLEAN found;
UCHAR mcr;
UCHAR msr;
found = FALSE;
/* save Modem Control Register (MCR) */
mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
/* enable loop mode (set Bit 4 of the MCR) */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* clear all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0x00)
{
/* set all modem output bits */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
/* read the Modem Status Register */
msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
/*
* the upper nibble of the MSR (modem output bits) must be
* equal to the lower nibble of the MCR (modem input bits)
*/
if ((msr & 0xF0) == 0xF0)
{
/*
* setup a resonable state for the port:
* enable fifo and clear recieve/transmit buffers
*/
WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
(SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
READ_PORT_UCHAR (SER_RBR(BaseAddress));
WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
found = TRUE;
}
}
/* restore MCR */
WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
return (found);
}
/* FUNCTIONS ****************************************************************/
/* HAL.KdPortInitialize */
BOOLEAN
STDCALL
KdPortInitialize (
PKD_PORT_INFORMATION PortInformation,
ULONG Unknown1,
ULONG Unknown2
)
{
ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
char buffer[80];
ULONG divisor;
UCHAR lcr;
if (PortInitialized == FALSE)
{
if (PortInformation->BaudRate != 0)
{
BaudRate = PortInformation->BaudRate;
}
else
{
BaudRate = DEFAULT_BAUD_RATE;
}
if (PortInformation->ComPort == 0)
{
if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
{
PortBase = (PUCHAR)BaseArray[2];
ComPort = 2;
PortInformation->BaseAddress = (ULONG)PortBase;
PortInformation->ComPort = ComPort;
#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif /* NDEBUG */
}
else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
{
PortBase = (PUCHAR)BaseArray[1];
ComPort = 1;
PortInformation->BaseAddress = (ULONG)PortBase;
PortInformation->ComPort = ComPort;
#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif /* NDEBUG */
}
else
{
sprintf (buffer,
"\nKernel Debugger: No COM port found!!!\n\n");
HalDisplayString (buffer);
return FALSE;
}
}
else
{
if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
{
PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
ComPort = PortInformation->ComPort;
PortInformation->BaseAddress = (ULONG)PortBase;
#ifndef NDEBUG
sprintf (buffer,
"\nSerial port COM%ld found at 0x%lx\n",
ComPort,
(ULONG)PortBase);
HalDisplayString (buffer);
#endif /* NDEBUG */
}
else
{
sprintf (buffer,
"\nKernel Debugger: No serial port found!!!\n\n");
HalDisplayString (buffer);
return FALSE;
}
}
PortInitialized = TRUE;
}
/*
* set baud rate and data format (8N1)
*/
/* turn on DTR and RTS */
WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
/* set DLAB */
lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
/* set baud rate */
divisor = 115200 / BaudRate;
WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
/* reset DLAB and set 8N1 format */
WRITE_PORT_UCHAR (SER_LCR(PortBase),
SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
/* read junk out of the RBR */
lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
/*
* set global info
*/
*KdComPortInUse = PortBase;
/*
* print message to blue screen
*/
sprintf (buffer,
"\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
ComPort,
(ULONG)PortBase,
BaudRate);
HalDisplayString (buffer);
return TRUE;
}
/* HAL.KdPortInitializeEx */
BOOLEAN
STDCALL
KdPortInitializeEx (
PKD_PORT_INFORMATION PortInformation,
ULONG Unknown1,
ULONG Unknown2
)
{
ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
PUCHAR ComPortBase;
char buffer[80];
ULONG divisor;
UCHAR lcr;
if (PortInformation->BaudRate == 0)
{
PortInformation->BaudRate = DEFAULT_BAUD_RATE;
}
if (PortInformation->ComPort == 0)
{
return FALSE;
}
else
{
if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -