📄 kdtran.c
字号:
/*++Copyright (c) 1990-2000 Microsoft Corporation. All rights reserved.Module Name: kdtran.cAbstract: This module implements the I/O comunications for the serial transport.Revision History:--*/#include <windows.h>#include <ethdbg.h>#include <halether.h>#include "kdp.h"#if 0#define DBGPRT(cp) OEMWriteOtherDebugString(cp)#else#define DBGPRT(cp)#endif#define MAXIMUM_RETRIES 1024*128BOOL KdpUseTCPSockets;BOOL KdpUseUDPSockets;BOOL KdpUseEdbg;static BOOL fIntsOff;// Pointer to buffer for formatting KDBG commands to send over ether. Is set in the// EdbgRegisterDfltClient function. Size of buffer is EDBG_MAX_DATA_SIZE.static UCHAR *KdbgEthBuf;static int (*ReadDebugByte)() = OEMReadDebugByte;static void (*WriteDebugByte)(BYTE ch) = OEMWriteDebugByte;// Locals for handling translation of the packet based ethernet commands to the byte read and// write commands used by kdstub.static UCHAR *pWritePtr, *pReadPtr;static DWORD dwRemainingBytes;static DWORD dwBytesWrittenToBuffer;// Fill receive buffer - note that we must call the EDBG routines with interrupts// disabled, since for the debugger we can't use critical sections or KCalls to// protect accesses to the hardware (we can't block, and KCalls turn on ints// for some systems).BOOL FillEdbgBuffer(){ DWORD dwLen = EDBG_MAX_DATA_SIZE; // Note that we can't trust our flag to tell us whether ints are enabled // at this point - if the debugger needs to access the loader for example // for a page fault, ints may be turned on by the kernel. INTERRUPTS_OFF(); if (!pEdbgRecv(EDBG_SVC_KDBG, KdbgEthBuf,&dwLen, 0)) { if (!fIntsOff) { INTERRUPTS_ON(); } return FALSE; } dwRemainingBytes = dwLen; pReadPtr = KdbgEthBuf; if (!fIntsOff) { INTERRUPTS_ON(); } return TRUE;}BOOL WriteEdbgBuffer(){ INTERRUPTS_OFF(); if (dwBytesWrittenToBuffer && !pEdbgSend(EDBG_SVC_KDBG,KdbgEthBuf,dwBytesWrittenToBuffer)) { if (!fIntsOff) { INTERRUPTS_ON(); } return FALSE; } dwBytesWrittenToBuffer = 0; pWritePtr = KdbgEthBuf; if (!fIntsOff) { INTERRUPTS_ON(); } return TRUE;}static void send_byte_ether(BYTE ch){ *pWritePtr++ = ch; if (++dwBytesWrittenToBuffer == EDBG_MAX_DATA_SIZE) WriteEdbgBuffer();}static int get_byte_ether(){ // Refill buffer if necessary and return next byte if (dwRemainingBytes == 0) if (!FillEdbgBuffer()) return OEM_DEBUG_READ_NODATA; dwRemainingBytes--; return *pReadPtr++;}// Attempt to switch Kdbg over to ethernet. Will fail if no support// for this in the HAL.BOOL SwitchKdbgToEther(BOOL ToEther){ BOOL Ret=TRUE; if (ToEther) { if (pEdbgRegisterDfltClient && pEdbgRegisterDfltClient(EDBG_SVC_KDBG,0,&KdbgEthBuf,&KdbgEthBuf)) { dwBytesWrittenToBuffer = 0; pWritePtr = KdbgEthBuf; KdpUseEdbg = TRUE; ReadDebugByte = get_byte_ether; WriteDebugByte = send_byte_ether; } else Ret = KdpUseEdbg = FALSE; } else { ReadDebugByte = OEMReadDebugByte; WriteDebugByte = OEMWriteDebugByte; } return Ret;}/*++Routine Description: This routine gets a byte from the serial port used by the kernel debugger.Arguments: Input - Supplies a pointer to a variable that receives the input data byte.Return Value: CP_GET_SUCCESS is returned if a byte is successfully read from the kernel debugger line. CP_GET_ERROR is returned if an error is encountered during reading. CP_GET_NODATA is returned if timeout occurs.--*/USHORT KdPortGetByte(OUT PUCHAR Input){ int ret; UINT limitcount = MAXIMUM_RETRIES; while (limitcount != 0) { limitcount--; ret = ReadDebugByte(); if (ret == OEM_DEBUG_COM_ERROR) return CP_GET_ERROR; else if (ret != OEM_DEBUG_READ_NODATA) { *Input=(unsigned char)ret; return CP_GET_SUCCESS; } } return CP_GET_NODATA;}/*++Routine Description: This routine puts a byte to the serial port used by the kernel debugger.Arguments: Output - Supplies the output data byte.Return Value: None.--*/VOID KdPortPutByte(IN UCHAR Output){ WriteDebugByte(Output);}/*++Routine Description: This routine clears the channel B error flagArguments: None.Return Value: None.--*/VOID KdClearCommError(VOID) { OEMClearDebugCommError();}VOID KdInterruptsOff(VOID) { fIntsOff = TRUE; INTERRUPTS_OFF();}VOID KdInterruptsOn(VOID) { fIntsOff = FALSE; INTERRUPTS_ON();}VOID KdInitTransport(VOID) { // This routine does not do anything when using serial transport.}VOID KdTerminateTransport(VOID) { // This routine does not do anything when using serial transport.}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -