mirror of https://github.com/acidanthera/audk.git
99 lines
3.4 KiB
C
99 lines
3.4 KiB
C
/** @file
|
|
Platform Hook Library instance for UART device.
|
|
|
|
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Base.h>
|
|
#include <Uefi/UefiBaseType.h>
|
|
#include <Library/PciLib.h>
|
|
#include <Library/PlatformHookLib.h>
|
|
#include <Library/BlParseLib.h>
|
|
#include <Library/PcdLib.h>
|
|
|
|
typedef struct {
|
|
UINT16 VendorId; ///< Vendor ID to match the PCI device. The value 0xFFFF terminates the list of entries.
|
|
UINT16 DeviceId; ///< Device ID to match the PCI device
|
|
UINT32 ClockRate; ///< UART clock rate. Set to 0 for default clock rate of 1843200 Hz
|
|
UINT64 Offset; ///< The byte offset into to the BAR
|
|
UINT8 BarIndex; ///< Which BAR to get the UART base address
|
|
UINT8 RegisterStride; ///< UART register stride in bytes. Set to 0 for default register stride of 1 byte.
|
|
UINT16 ReceiveFifoDepth; ///< UART receive FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
|
|
UINT16 TransmitFifoDepth; ///< UART transmit FIFO depth in bytes. Set to 0 for a default FIFO depth of 16 bytes.
|
|
UINT8 Reserved[2];
|
|
} PCI_SERIAL_PARAMETER;
|
|
|
|
/**
|
|
Performs platform specific initialization required for the CPU to access
|
|
the hardware associated with a SerialPortLib instance. This function does
|
|
not initialize the serial port hardware itself. Instead, it initializes
|
|
hardware devices that are required for the CPU to access the serial port
|
|
hardware. This function may be called more than once.
|
|
|
|
@retval RETURN_SUCCESS The platform specific initialization succeeded.
|
|
@retval RETURN_DEVICE_ERROR The platform specific initialization could not be completed.
|
|
|
|
**/
|
|
RETURN_STATUS
|
|
EFIAPI
|
|
PlatformHookSerialPortInitialize (
|
|
VOID
|
|
)
|
|
{
|
|
RETURN_STATUS Status;
|
|
UINT32 DeviceVendor;
|
|
PCI_SERIAL_PARAMETER *SerialParam;
|
|
SERIAL_PORT_INFO SerialPortInfo;
|
|
|
|
Status = ParseSerialInfo (&SerialPortInfo);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (SerialPortInfo.Type == PLD_SERIAL_TYPE_MEMORY_MAPPED) {
|
|
Status = PcdSetBoolS (PcdSerialUseMmio, TRUE);
|
|
} else { //IO
|
|
Status = PcdSetBoolS (PcdSerialUseMmio, FALSE);
|
|
}
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
Status = PcdSet64S (PcdSerialRegisterBase, SerialPortInfo.BaseAddr);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PcdSet32S (PcdSerialRegisterStride, SerialPortInfo.RegWidth);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PcdSet32S (PcdSerialBaudRate, SerialPortInfo.Baud);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PcdSet64S (PcdUartDefaultBaudRate, SerialPortInfo.Baud);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PcdSet32S (PcdSerialClockRate, SerialPortInfo.InputHertz);
|
|
if (RETURN_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (SerialPortInfo.UartPciAddr >= 0x80000000) {
|
|
DeviceVendor = PciRead32 (SerialPortInfo.UartPciAddr & 0x0ffff000);
|
|
SerialParam = PcdGetPtr(PcdPciSerialParameters);
|
|
SerialParam->VendorId = (UINT16)DeviceVendor;
|
|
SerialParam->DeviceId = DeviceVendor >> 16;
|
|
SerialParam->ClockRate = SerialPortInfo.InputHertz;
|
|
SerialParam->RegisterStride = (UINT8)SerialPortInfo.RegWidth;
|
|
}
|
|
|
|
return RETURN_SUCCESS;
|
|
}
|