diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c b/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c new file mode 100644 index 00000000..621c6bce --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiPayloadPkg/Library/PlatformHookLib/PlatformHookLib.c @@ -0,0 +1,98 @@ +/** @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; +} |