HyperDbg/hyperdbg/kdserial/usif.c
copilot-swe-agent[bot] 774d61782f
fix: correct typos and one copy-paste error in comments and messages
Agent-Logs-Url: https://github.com/HyperDbg/HyperDbg/sessions/0817c887-8808-4080-a701-6a0211b10595

Co-authored-by: SinaKarvandi <13383992+SinaKarvandi@users.noreply.github.com>
2026-04-23 12:38:48 +00:00

270 lines
5.2 KiB
C

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
usif.c
Abstract:
Intel Sofia UART serial support.
--*/
// ------------------------------------------------------------------- Includes
#include "common.h"
// ---------------------------------------------------------------- Definitions
#define USIF_FIFO_STAT 0x00000044 // FIFO status register
#define USIF_FIFO_STAT_TXFFS 0x00FF0000 // TX filled FIFO stages
#define USIF_FIFO_STAT_RXFFS 0x000000FF // RX filled FIFO stages
#define USIF_TXD 0x00040000 // Transmission data register
#define USIF_RXD 0x00080000 // Reception data register
// ------------------------------------------------------------------ Functions
BOOLEAN
UsifInitializePort(
_In_opt_ _Null_terminated_ PCHAR LoadOptions,
_Inout_ PCPPORT Port,
BOOLEAN MemoryMapped,
UCHAR AccessSize,
UCHAR BitWidth)
/*++
Routine Description:
This routine performs the initialization of an Intel Sofia serial UART.
Arguments:
LoadOptions - Optional load option string. Currently unused.
Port - Supplies a pointer to a CPPORT object which will be filled in as
part of the port initialization.
MemoryMapped - Supplies a boolean which indicates if the UART is accessed
through memory-mapped registers or legacy port I/O.
AccessSize - Supplies an ACPI Generic Access Size value which indicates the
type of bus access that should be performed when accessing the UART.
BitWidth - Supplies a number indicating how wide the UART's registers are.
Return Value:
TRUE if the port has been successfully initialized, FALSE otherwise.
--*/
{
UNREFERENCED_PARAMETER(LoadOptions);
UNREFERENCED_PARAMETER(AccessSize);
UNREFERENCED_PARAMETER(BitWidth);
if (MemoryMapped == FALSE)
{
return FALSE;
}
Port->Flags = 0;
return TRUE;
}
BOOLEAN
UsifSetBaud(
_Inout_ PCPPORT Port,
ULONG Rate)
/*++
Routine Description:
Set the baud rate for the UART hardware and record it in the port object.
Arguments:
Port - Supplies the address of the port object that describes the UART.
Rate - Supplies the desired baud rate in bits per second.
Return Value:
TRUE if the baud rate was programmed, FALSE if it was not.
--*/
{
if ((Port == NULL) || (Port->Address == NULL))
{
return FALSE;
}
//
// Remember the baud rate.
//
Port->BaudRate = Rate;
return TRUE;
}
UART_STATUS
UsifGetByte(
_Inout_ PCPPORT Port,
_Out_ PUCHAR Byte)
/*++
Routine Description:
Fetch a data byte from the UART device and return it.
Arguments:
Port - Supplies the address of the port object that describes the UART.
Byte - Supplies the address of variable to hold the result.
Return Value:
UART_STATUS code.
--*/
{
ULONG Stat;
ULONG Value;
*Byte = 0;
if ((Port == NULL) || (Port->Address == NULL))
{
return UartNotReady;
}
//
// Get FIFO status.
//
Stat = READ_REGISTER_ULONG((PULONG)(Port->Address + USIF_FIFO_STAT));
//
// Is at least one character available?
//
if ((Stat & USIF_FIFO_STAT_RXFFS) != 0)
{
//
// Fetch the data byte.
//
Value = READ_REGISTER_ULONG((PULONG)(Port->Address + USIF_RXD));
*Byte = Value & (UCHAR)0xFF;
return UartSuccess;
}
return UartNoData;
}
UART_STATUS
UsifPutByte(
_Inout_ PCPPORT Port,
UCHAR Byte,
BOOLEAN BusyWait)
/*++
Routine Description:
Write a data byte out to the UART device.
Arguments:
Port - Supplies the address of the port object that describes the UART.
Byte - Supplies the data to emit.
BusyWait - Supplies a flag to control whether this routine will busy
wait (spin) for the UART hardware to be ready to transmit.
Return Value:
UART_STATUS code.
--*/
{
if ((Port == NULL) || (Port->Address == NULL))
{
return UartNotReady;
}
//
// Wait for port to be free and FIFO not full.
//
if (BusyWait != FALSE)
{
while (READ_REGISTER_ULONG((PULONG)(Port->Address + USIF_FIFO_STAT)) &
(USIF_FIFO_STAT_TXFFS))
;
}
else if (READ_REGISTER_ULONG((PULONG)(Port->Address + USIF_FIFO_STAT)) &
(USIF_FIFO_STAT_TXFFS))
{
return UartNotReady;
}
//
// Send the byte.
//
WRITE_REGISTER_ULONG((PULONG)(Port->Address + USIF_TXD), (ULONG)Byte);
return UartSuccess;
}
BOOLEAN
UsifRxReady(
_Inout_ PCPPORT Port)
/*++
Routine Description:
This routine determines if there is data pending in the UART.
Arguments:
Port - Supplies the address of the port object that describes the UART.
Return Value:
TRUE if data is available, FALSE otherwise.
--*/
{
ULONG Stat;
if ((Port == NULL) || (Port->Address == NULL))
{
return FALSE;
}
//
// Read the STAT Register to determine if there is any pending
// data to read.
//
Stat = READ_REGISTER_ULONG((PULONG)(Port->Address + USIF_FIFO_STAT));
if ((Stat & USIF_FIFO_STAT_RXFFS) != 0)
{
return TRUE;
}
return FALSE;
}