singrdk/base/Kernel/Native/HalKdCom.cpp

159 lines
4.8 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: halkdcom.cpp: pc-compatible com port serial transport.
//
// Note: Kernel Only
//
#include "hal.h"
#include "halkd.h"
//
// Debugger Debugging
//
#define KDDBG if (0) kdprintf
#define KDDBG2 if (0) kdprintf
////////////////////////////////////////////////////////// COM PORT Constants.
//
#define COM1_PORT 0x03f8
#define COM2_PORT 0x02f8
#define COM3_PORT 0x03e8
#define COM4_PORT 0x02e8
#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
const UINT16 BaudRate = 1; // 115200 bps
#define COM_DATRDY 0x01
#define COM_OUTRDY 0x20
#define LC_DLAB 0x80
#define CLOCK_RATE 0x1C200 // USART clock rate
#define MC_DTRRTS 0x03 // Control bits to assert DTR and RTS
#define MS_DSRCTSCD 0xB0 // Status bits for DSR, CTS and CD
#define MS_CD 0x80
#define SERIAL_MCR_LOOP 0x10 // enables loopback testing mode
#define SERIAL_MCR_OUT1 0x04 // general purpose output.
#define SERIAL_MSR_CTS 0x10 // (complemented) state of clear to send (CTS).
#define SERIAL_MSR_DSR 0x20 // (complemented) state of data set ready (DSR).
#define SERIAL_MSR_RI 0x40 // (complemented) state of ring indicator (RI).
#define SERIAL_MSR_DCD 0x80 // (complemented) state of data carrier detect (DCD).
//
// Globals
//
static UINT16 KdBasePort = COM2_PORT;
////////////////////////////////////////////////// Serial Port Input & Output.
//
static UINT8 KdReadInt8(UINT16 port)
{
return __inbyte(port);
}
static void KdWriteInt8(UINT16 port, UINT8 value)
{
__outbyte(port, value);
}
bool KdpSerialInit(Class_Microsoft_Singularity_Hal_Platform *nbi)
// Initializes the communication port (baud rate, parity etc.)
{
KdBasePort = (UINT16)nbi->DebugBasePort;
if (KdBasePort < 0x100) {
KdBasePort = 0;
return false;
}
// turn off interrupts
KdWriteInt8(KdBasePort + COM_LCR, 0x00);
KdWriteInt8(KdBasePort + COM_IEN, 0x00);
// Turn on DTS/RTS
KdWriteInt8(KdBasePort + COM_MCR, MC_DTRRTS); // Needed for VirtualPC PIPE/Serial
// Turn on FIFO
//KdWriteInt8(KdBasePort + COM_FCR, 1);
// Set the baud rate
KdWriteInt8(KdBasePort + COM_LCR, LC_DLAB); // Divisor latch access bit
KdWriteInt8(KdBasePort + COM_DLM, (UINT8)(BaudRate >> 8));
KdWriteInt8(KdBasePort + COM_DLL, (UINT8)(BaudRate & 0xFF));
// initialize the LCR
KdWriteInt8(KdBasePort + COM_LCR, 0x03);
// 8 data bits, 1 stop bit, no parity, no break
// See if the 16450/16550 scratch register is available.
// If not, we'll assume the serial port doesn't really exist.
KdWriteInt8(KdBasePort + COM_SCR, 0xff);
UINT8 a1 = KdReadInt8(KdBasePort + COM_SCR);
KdWriteInt8(KdBasePort + COM_SCR, 0x00);
UINT8 a2 = KdReadInt8(KdBasePort + COM_SCR);
return (bool) ((a1 == (UINT8)0xff) && (a2 == (UINT8)0x00));
}
//
// Define wait timeout value.
//
#define TIMEOUT_COUNT 1024 * 1000
// #define TIMEOUT_COUNT 1024 * 200
//#define TIMEOUT_COUNT 15
KDP_STATUS KdpSerialGetByte(OUT PUCHAR Input, BOOL WaitForByte)
{
UCHAR lsr;
UCHAR value;
UINT32 limitcount = WaitForByte ? TIMEOUT_COUNT : 1;
UCHAR msr;
msr = KdReadInt8(KdBasePort + COM_MSR);
KDDBG2("MSR %02x\n", msr);
while (limitcount != 0) {
limitcount--;
lsr = KdReadInt8(KdBasePort + COM_LSR);
KDDBG2("LSR %02x\n", lsr);
if (lsr & COM_DATRDY) {
value = KdReadInt8(KdBasePort + COM_DAT);
*Input = value & 0xff;
return KDP_PACKET_RECEIVED;
}
}
return KDP_PACKET_TIMEOUT;
}
void KdpSerialPutByte(IN UCHAR Output)
{
// wait for the com port to be ready
while ((KdReadInt8( KdBasePort + COM_LSR ) & COM_OUTRDY) == 0) {
// nop;
}
// write a single char
KdWriteInt8(KdBasePort + COM_DAT, Output);
}
//
///////////////////////////////////////////////////////////////// End of File.