From c5a7d0fe05926ad3c2387d7b809c42200bb48790 Mon Sep 17 00:00:00 2001 From: belliash Date: Mon, 2 Jan 2023 16:14:00 +0100 Subject: [PATCH] Improvements in COM port support --- sdk/xtdk/hlfuncs.h | 8 ++-- sdk/xtdk/hltypes.h | 2 +- xtldr/efiutil.c | 54 ++++++++++++---------- xtoskrnl/hl/cport.c | 108 ++++++++++++++++++++++---------------------- 4 files changed, 88 insertions(+), 84 deletions(-) diff --git a/sdk/xtdk/hlfuncs.h b/sdk/xtdk/hlfuncs.h index 69ea0be..90f8833 100644 --- a/sdk/xtdk/hlfuncs.h +++ b/sdk/xtdk/hlfuncs.h @@ -26,13 +26,13 @@ HlComPortGetByte(IN PCPPORT Port, IN BOOLEAN Poll); XTCDECL -UCHAR -HlComPortReadLsr(IN PCPPORT Port, +XTSTATUS +HlComPortPutByte(IN PCPPORT Port, IN UCHAR Byte); XTCDECL -XTSTATUS -HlComPortPutByte(IN PCPPORT Port, +UCHAR +HlComPortReadLsr(IN PCPPORT Port, IN UCHAR Byte); XTCDECL diff --git a/sdk/xtdk/hltypes.h b/sdk/xtdk/hltypes.h index cb5ef83..c92a27d 100644 --- a/sdk/xtdk/hltypes.h +++ b/sdk/xtdk/hltypes.h @@ -88,7 +88,7 @@ #define COMPORT_REG_MCR 0x04 /* Modem Control Register */ #define COMPORT_REG_LSR 0x05 /* Line Status Register */ #define COMPORT_REG_MSR 0x06 /* Modem Status Register */ -#define COMPROT_REG_SR 0x07 /* Scratch Register */ +#define COMPORT_REG_SR 0x07 /* Scratch Register */ /* Serial (COM) port initial state */ typedef struct _CPPORT diff --git a/xtldr/efiutil.c b/xtldr/efiutil.c index d3d4c25..243fc27 100644 --- a/xtldr/efiutil.c +++ b/xtldr/efiutil.c @@ -73,34 +73,30 @@ BlComPortInitialize() Argument++; } - /* Check for some custom COM port (COM0 means non-default one) */ - if(PortNumber == 0) + /* Check if custom COM port address supplied */ + if(PortNumber == 0 && RtlWideStringCompare(Argument, L":0x", 3) == 0) { - /* Look for COM port address */ - if(RtlWideStringCompare(Argument, L",0x", 3) == 0) + /* COM port address provided */ + Argument += 3; + while((*Argument >= '0' && *Argument <= '9') || + (*Argument >= 'A' && *Argument <= 'F') || + (*Argument >= 'a' && *Argument <= 'f')) { - /* COM port address provided */ - Argument += 3; - while((*Argument >= '0' && *Argument <= '9') || - (*Argument >= 'A' && *Argument <= 'F') || - (*Argument >= 'a' && *Argument <= 'f')) + /* Get port address */ + PortAddress *= 16; + if(*Argument >= '0' && *Argument <= '9') { - /* Get port address */ - PortAddress *= 16; - if(*Argument >= '0' && *Argument <= '9') - { - PortAddress += *Argument - '0'; - } - else if(*Argument >= 'A' && *Argument <= 'F') - { - PortAddress += *Argument - 'A' + 10; - } - else if(*Argument >= 'a' && *Argument <= 'f') - { - PortAddress += *Argument - 'a' + 10; - } - Argument++; + PortAddress += *Argument - '0'; } + else if(*Argument >= 'A' && *Argument <= 'F') + { + PortAddress += *Argument - 'A' + 10; + } + else if(*Argument >= 'a' && *Argument <= 'f') + { + PortAddress += *Argument - 'a' + 10; + } + Argument++; } } @@ -128,6 +124,16 @@ BlComPortInitialize() } } + /* Print debug message depending on port settings */ + if(PortAddress) + { + BlEfiPrint(L"Initializing serial console at COM port address: %lx\n", PortAddress); + } + else + { + BlEfiPrint(L"Initializing serial console at port COM%d\n", PortNumber); + } + /* Initialize COM port */ Status = HlInitializeComPort(&EfiSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate); if(Status != STATUS_SUCCESS) diff --git a/xtoskrnl/hl/cport.c b/xtoskrnl/hl/cport.c index 809d5bf..e12614c 100644 --- a/xtoskrnl/hl/cport.c +++ b/xtoskrnl/hl/cport.c @@ -93,47 +93,6 @@ HlComPortGetByte(IN PCPPORT Port, return STATUS_NOT_FOUND; } -/** - * Reads LSR from specified serial port. - * - * @param Port - * Address of COM port. - * - * @param Byte - * Value expected from the port. - * - * @return Byte read from COM port. - * - * @since XT 1.0 - */ -XTCDECL -UCHAR -HlComPortReadLsr(IN PCPPORT Port, - IN UCHAR Byte) -{ - UCHAR Lsr, Msr; - STATIC UCHAR RingFlag; - - /* Read the Line Status Register (LSR) */ - Lsr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR)); - - /* Check if expected byte is present */ - if((Lsr & Byte) == 0) - { - /* Check Modem Status Register (MSR) for ring indicator */ - Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)); - RingFlag |= (Msr & COMPORT_MSR_RI) ? 1 : 2; - if(RingFlag == 3) - { - /* Ring indicator toggled, use modem control */ - Port->Flags |= COMPORT_FLAG_MC; - } - } - - /* Return byte read */ - return Lsr; -} - /** * This routine writes a byte to the serial port. * @@ -191,6 +150,47 @@ HlComPortPutByte(IN PCPPORT Port, return STATUS_SUCCESS; } +/** + * Reads LSR from specified serial port. + * + * @param Port + * Address of COM port. + * + * @param Byte + * Value expected from the port. + * + * @return Byte read from COM port. + * + * @since XT 1.0 + */ +XTCDECL +UCHAR +HlComPortReadLsr(IN PCPPORT Port, + IN UCHAR Byte) +{ + UCHAR Lsr, Msr; + STATIC UCHAR RingFlag; + + /* Read the Line Status Register (LSR) */ + Lsr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_LSR)); + + /* Check if expected byte is present */ + if((Lsr & Byte) == 0) + { + /* Check Modem Status Register (MSR) for ring indicator */ + Msr = HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_MSR)); + RingFlag |= (Msr & COMPORT_MSR_RI) ? 1 : 2; + if(RingFlag == 3) + { + /* Ring indicator toggled, use modem control */ + Port->Flags |= COMPORT_FLAG_MC; + } + } + + /* Return byte read */ + return Lsr; +} + /** * This routine initializes the COM port. * @@ -217,9 +217,9 @@ HlInitializeComPort(IN OUT PCPPORT Port, IN PUCHAR PortAddress, IN ULONG BaudRate) { - PUCHAR Address; - UCHAR Byte = 0; USHORT Flags = 0; + UCHAR Byte = 0; + PUCHAR Address; ULONG Mode; /* We support only a pre-defined number of ports */ @@ -266,12 +266,13 @@ HlInitializeComPort(IN OUT PCPPORT Port, do { /* Check whether the 16450/16550 scratch register exists */ - HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPROT_REG_SR), Byte); - if(HlIoPortInByte(PtrToUshort(Address + (ULONG)COMPROT_REG_SR)) != Byte) + HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_SR), Byte); + if(HlIoPortInByte(PtrToUshort(Address + (ULONG)COMPORT_REG_SR)) != Byte) { return STATUS_NOT_FOUND; } - } while(++Byte != 0); + } + while(++Byte != 0); /* Disable interrupts */ HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_LCR), COMPORT_LSR_DIS); @@ -297,19 +298,16 @@ HlInitializeComPort(IN OUT PCPPORT Port, HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_FCR), COMPORT_FCR_ENABLE | COMPORT_FCR_RCVR_RESET | COMPORT_FCR_TXMT_RESET); - /* Enable loopback mode and test serial port */ - HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_LOOP); - HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_RBR), COMPORT_MSR_TST); - if(HlIoPortInByte(PtrToUshort(Address + (ULONG)COMPORT_REG_RBR)) != COMPORT_MSR_TST) - { - return STATUS_IO_DEVICE_ERROR; - } - /* Mark port as fully initialized */ Flags |= COMPORT_FLAG_INIT; - /* Disable loopback mode and use port normally */ + /* Make sure port works in Normal Operation Mode (NOM) */ HlIoPortOutByte(PtrToUshort(Address + (ULONG)COMPORT_REG_MCR), COMPORT_MCR_NOM); + + /* Read junk data out of the Receive Buffer Register (RBR) */ + HlIoPortInByte(PtrToUshort(Port->Address + (ULONG)COMPORT_REG_RBR)); + + /* Store port details */ Port->Address = Address; Port->Baud = BaudRate; Port->Flags = Flags;