diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/ME/ActiveManagement/Sol | |
download | zprj-master.tar.xz |
Diffstat (limited to 'ReferenceCode/ME/ActiveManagement/Sol')
7 files changed, 2960 insertions, 0 deletions
diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c new file mode 100644 index 0000000..3e6ba9f --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/ComponentName.c @@ -0,0 +1,187 @@ +/** @file + This portion is to register the Serial over Lan Controller Driver name + +@copyright + Copyright (c) 2004 - 2012 Intel Corporation. All rights + reserved This software and associated documentation (if any) + is furnished under a license and may only be used or copied in + accordance with the terms of the license. Except as permitted + by such license, no part of this software or documentation may + be reproduced, stored in a retrieval system, or transmitted in + any form or by any means without the express written consent + of Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement +**/ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "PciSerial.h" +#endif +// +// EFI Component Name Functions +// +EFI_STATUS +EFIAPI +PciSerialComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +PciSerialComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL mPciSerialComponentName = { + PciSerialComponentNameGetDriverName, + PciSerialComponentNameGetControllerName, + "eng" +}; + +static EFI_UNICODE_STRING_TABLE mPciSerialDriverNameTable[] = { + { + "eng", + L"PCI Serial Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[in] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned in DriverName. + @retval EFI_INVALID_PARAMETER Language or DriverName is NULL. + @exception EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. +**/ +EFI_STATUS +EFIAPI +PciSerialComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString ( + Language, + mPciSerialComponentName.SupportedLanguages, + mPciSerialDriverNameTable, + DriverName + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[in] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language + specified by Language from the point of view of the + driver specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE. Language or + ControllerName is NULL. + @exception EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. The driver specified by This + does not support the language specified by Language. +**/ +EFI_STATUS +EFIAPI +PciSerialComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + SERIAL_DEV *SerialDevice; + + /// + /// This is a device driver, so ChildHandle must be NULL. + /// + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + /// + /// Get the Block I/O Protocol on Controller + /// + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + mPciSerialControllerDriverBinding.DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Get the Serial Controller's Device structure + /// + SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); + + return LookupUnicodeString ( + Language, + mPciSerialComponentName.SupportedLanguages, + SerialDevice->ControllerNameTable, + ControllerName + ); +} diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c new file mode 100644 index 0000000..6dba7fa --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.c @@ -0,0 +1,1807 @@ +/** @file + PCI Serial driver for standard UARTS on an PCI bus. + Customized for Intel AMT SErial OVer LAN (82573E-Tekoa) 16550 UART Driver. + +@copyright + Copyright (c) 2004 - 2012 Intel Corporation. All rights + reserved This software and associated documentation (if any) + is furnished under a license and may only be used or copied in + accordance with the terms of the license. Except as permitted + by such license, no part of this software or documentation may + be reproduced, stored in a retrieval system, or transmitted in + any form or by any means without the express written consent + of Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ + +// +// External include files do NOT need to be explicitly specified in real EDKII +// environment +// +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueDxe.h" +#include "PciSerial.h" +#include "MeAccess.h" +#endif + +// +// PCI Serial Driver Binding Protocol +// +EFI_DRIVER_BINDING_PROTOCOL mPciSerialControllerDriverBinding = { + PciSerialControllerDriverSupported, + PciSerialControllerDriverStart, + PciSerialControllerDriverStop, + 0x10, + NULL, + NULL +}; + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND The device doesn't support or relative environment not ready +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + UART_DEVICE_PATH UartNode; + UINT16 Buffer[2]; + UINT16 Temp; + UINT8 *ByteBuffer; + + /// + /// Init AMT library + /// + Status = AmtLibInit (); + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// We don't want the SOL Controller enabled unless + /// there is an remote control request. The AMT usage model + /// dictates this. Thus here we check for the ASF Remote + /// Control command wants SOL before we start the controller. + /// + if (ActiveManagementEnableSol () == FALSE) { + return EFI_NOT_FOUND; + } + /// + /// Open the IO Abstraction(s) needed to perform the supported test + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + /// + /// Now test the EfiPciIoProtocol + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (Status == EFI_ALREADY_STARTED) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Use the PCI I/O Protocol to see if Controller is standard ISA UART that + /// can be managed by this driver. + /// + Status = EFI_SUCCESS; + + /// + /// Looks for a PCI CLASS / SUBCLASS / INTERFACE of 0x07 / 0x00 / 0x02 + /// To allow supportting all PCI Devices that are 16550 compatible UARTS. + /// + /// This is point where Tekoa iAMT SOL support enabling via + /// Get Boot Options ASF info is used to customize PCISerial + /// to work for iAMT. + /// + /// Also if want general PCI Serial com devices to work as well + /// can duplicate this driver one for tekoa and iAMT and the other + /// for general serial devices. + /// + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + (UINT32) PCI_VENDOR_ID_OFFSET, + (UINTN) 1, + (VOID *) &Buffer + ); + /// + /// If Buffer is Not Valid (no setup info in NVRAM/FLASH) use auto mode for PTBx cfg. + /// + if ((Buffer[0] != V_ME_SOL_VENDOR_ID) || !IS_PCH_LPT_SOL_DEVICE_ID(Buffer[1]) + ) { + Status = EFI_UNSUPPORTED; + goto Error; + } + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + (UINT32) PCI_REVISION_ID_OFFSET, + (UINTN) 1, + (VOID *) &Buffer + ); + ByteBuffer = (UINT8 *) Buffer; + if ((ByteBuffer[3] != PCI_CLASS_SCC) || (ByteBuffer[2] != PCI_SUBCLASS_SERIAL) || (ByteBuffer[1] != PCI_IF_16550)) { + Status = EFI_UNSUPPORTED; + goto Error; + } + /// + /// Make sure the PCI io space is enabled + /// + Temp = 0x0003; + PciIo->Pci.Write ( + PciIo, + EfiPciIoWidthUint16, + PCI_COMMAND_OFFSET, + 0x01, + (VOID*) &Temp + ); + + /// + /// Make sure RemainingDevicePath is valid + /// + if (RemainingDevicePath != NULL) { + Status = EFI_UNSUPPORTED; + CopyMem (&UartNode, (UART_DEVICE_PATH *) RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + if (UartNode.Header.Type != MESSAGING_DEVICE_PATH || + UartNode.Header.SubType != MSG_UART_DP || + DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode) != sizeof (UART_DEVICE_PATH) + ) { + goto Error; + } + + if (UartNode.BaudRate > SERIAL_PORT_MAX_BAUD_RATE) { + goto Error; + } + + if (UartNode.Parity < NoParity || UartNode.Parity > SpaceParity) { + goto Error; + } + + if (UartNode.DataBits < 5 || UartNode.DataBits > 8) { + goto Error; + } + + if (UartNode.StopBits < OneStopBit || UartNode.StopBits > TwoStopBits) { + goto Error; + } + + if ((UartNode.DataBits == 5) && (UartNode.StopBits == TwoStopBits)) { + goto Error; + } + + if ((UartNode.DataBits >= 6) && (UartNode.DataBits <= 8) && (UartNode.StopBits == OneFiveStopBits)) { + goto Error; + } + + Status = EFI_SUCCESS; + } + +Error: + /// + /// Close the I/O Abstraction(s) used to perform the supported test + /// + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; +} + +/** + This routine is called right after the .Supported() called + and return EFI_SUCCESS. Notes: The supported protocols are + checked but the Protocols are closed. + + @param[in] This A pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval Other The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + SERIAL_DEV *SerialDevice; + UINTN Index; + UART_DEVICE_PATH Node; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + CHAR16 SerialPortName[sizeof (PCI_SERIAL_PORT_NAME)]; + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; + UINTN EntryCount; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + UINT64 *Supports; + UINT64 Temp; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr; + VOID **Resources; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Temp1; + + SerialDevice = NULL; + + /// + /// Get the Parent Device Path + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + return Status; + } + /// + /// Grab the IO abstraction we need to get any work done + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + goto Error; + } + + if (Status == EFI_ALREADY_STARTED) { + + if (RemainingDevicePath == NULL) { + return EFI_SUCCESS; + } + /// + /// Make sure a child handle does not already exist. This driver can only + /// produce one child per serial port. + /// + Status = gBS->OpenProtocolInformation ( + Controller, + &gEfiPciIoProtocolGuid, + &OpenInfoBuffer, + &EntryCount + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = EFI_ALREADY_STARTED; + for (Index = 0; Index < EntryCount; Index++) { + if (OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) { + Status = gBS->OpenProtocol ( + OpenInfoBuffer[Index].ControllerHandle, + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + CopyMem (&Node, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + Status = SerialIo->SetAttributes ( + SerialIo, + Node.BaudRate, + SerialIo->Mode->ReceiveFifoDepth, + SerialIo->Mode->Timeout, + Node.Parity, + Node.DataBits, + Node.StopBits + ); + } + break; + } + } + + FreePool (OpenInfoBuffer); + return Status; + } + /// + /// Initialize the serial device instance + /// + SerialDevice = AllocatePool (sizeof (SERIAL_DEV)); + if (SerialDevice == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + ZeroMem (SerialDevice, sizeof (SERIAL_DEV)); + + SerialDevice->PciIo = PciIo; + SerialDevice->ParentDevicePath = ParentDevicePath; + SerialDevice->ControllerNameTable = NULL; + + StrCpy (SerialPortName, L"PCI Serial Port # "); + SerialPortName[sizeof (PCI_SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0'); + AddUnicodeString ( + "eng", + mPciSerialComponentName.SupportedLanguages, + &SerialDevice->ControllerNameTable, + (CHAR16 *) SerialPortName + ); + + Ptr = &Temp1; + Resources = (VOID **) &Ptr; + Supports = &Temp; + *Supports = 0x01; + for (Index = 0; Index < PCI_MAX_BAR; Index++) { + Status = SerialDevice->PciIo->GetBarAttributes ( + PciIo, + (UINT8) Index, + Supports, + Resources + ); + Ptr = *Resources; + if (Ptr->ResType == ACPI_ADDRESS_SPACE_TYPE_IO) { + SerialDevice->BarIndex = (UINT16) Index; + Status = EFI_SUCCESS; + break; + } + } + + if (PciSerialPortPresent (SerialDevice) != TRUE) { + Status = EFI_DEVICE_ERROR; + goto Error; + } + + SerialDevice->Signature = SERIAL_DEV_SIGNATURE; + SerialDevice->Type = UART16450; + SerialDevice->SoftwareLoopbackEnable = FALSE; + SerialDevice->HardwareFlowControl = FALSE; + SerialDevice->Handle = NULL; + SerialDevice->Receive.First = 0; + SerialDevice->Receive.Last = 0; + SerialDevice->Receive.Surplus = SERIAL_MAX_BUFFER_SIZE; + SerialDevice->Transmit.First = 0; + SerialDevice->Transmit.Last = 0; + SerialDevice->Transmit.Surplus = SERIAL_MAX_BUFFER_SIZE; + + /// + /// Serial I/O + /// + SerialDevice->SerialIo.Revision = EFI_SERIAL_IO_PROTOCOL_REVISION; + SerialDevice->SerialIo.Reset = PciSerialReset; + SerialDevice->SerialIo.SetAttributes = PciSerialSetAttributes; + SerialDevice->SerialIo.SetControl = PciSerialSetControl; + SerialDevice->SerialIo.GetControl = PciSerialGetControl; + SerialDevice->SerialIo.Write = PciSerialWrite; + SerialDevice->SerialIo.Read = PciSerialRead; + SerialDevice->SerialIo.Mode = &(SerialDevice->SerialMode); + + if (RemainingDevicePath != NULL) { + /// + /// Match the configuration of the RemainingDevicePath. IsHandleSupported() + /// already checked to make sure the RemainingDevicePath contains settings + /// that we can support. + /// + CopyMem (&SerialDevice->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH)); + } else { + /// + /// Build the device path by appending the UART node to the ParentDevicePath + /// from the WinNtIo handle. The Uart setings are zero here, since + /// SetAttribute() will update them to match the default setings. + /// + ZeroMem (&SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH)); + SerialDevice->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH; + SerialDevice->UartDevicePath.Header.SubType = MSG_UART_DP; + SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH)); + } + /// + /// Build the device path by appending the UART node to the ParentDevicePath + /// from the WinNtIo handle. The Uart setings are zero here, since + /// SetAttribute() will update them to match the current setings. + /// + SerialDevice->DevicePath = AppendDevicePathNode ( + ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath + ); + + if (SerialDevice->DevicePath == NULL) { + Status = EFI_DEVICE_ERROR; + goto Error; + } + /// + /// Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults. + /// + SerialDevice->SerialMode.ControlMask = SERIAL_PORT_DEFAULT_CONTROL_MASK; + SerialDevice->SerialMode.Timeout = SERIAL_PORT_DEFAULT_TIMEOUT; + SerialDevice->SerialMode.BaudRate = SerialDevice->UartDevicePath.BaudRate; + SerialDevice->SerialMode.ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH; + SerialDevice->SerialMode.DataBits = SerialDevice->UartDevicePath.DataBits; + SerialDevice->SerialMode.Parity = SerialDevice->UartDevicePath.Parity; + SerialDevice->SerialMode.StopBits = SerialDevice->UartDevicePath.StopBits; + + /// + /// Issue a reset to initialize the COM port + /// + Status = SerialDevice->SerialIo.Reset (&SerialDevice->SerialIo); + if (EFI_ERROR (Status)) { + Status = EFI_SUCCESS; + goto Error; + } + /// + /// Install protocol interfaces for the serial device. + /// + Status = gBS->InstallMultipleProtocolInterfaces ( + &SerialDevice->Handle, + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + &gEfiSerialIoProtocolGuid, + &SerialDevice->SerialIo, + NULL + ); + if (EFI_ERROR (Status)) { + goto Error; + } + /// + /// Open For Child Device + /// + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + SerialDevice->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + +Error: + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + if (SerialDevice) { + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + FreeUnicodeStringTable (SerialDevice->ControllerNameTable); + FreePool (SerialDevice); + } + } + + return Status; +} + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @retval EFI_DEVICE_ERROR Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UINTN Index; + BOOLEAN AllChildrenStopped; + EFI_SERIAL_IO_PROTOCOL *SerialIo; + SERIAL_DEV *SerialDevice; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status = gBS->HandleProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath + ); + + /// + /// Complete all outstanding transactions to Controller. + /// Don't allow any new transaction to Controller to be started. + /// + if (NumberOfChildren == 0) { + /// + /// Close the bus driver + /// + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + Status = gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return Status; + } + + AllChildrenStopped = TRUE; + + for (Index = 0; Index < NumberOfChildren; Index++) { + Status = gBS->OpenProtocol ( + ChildHandleBuffer[Index], + &gEfiSerialIoProtocolGuid, + (VOID **) &SerialIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + + SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo); + + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ChildHandleBuffer[Index] + ); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + &gEfiSerialIoProtocolGuid, + &SerialDevice->SerialIo, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + ChildHandleBuffer[Index], + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + } else { + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + FreeUnicodeStringTable (SerialDevice->ControllerNameTable); + FreePool (SerialDevice); + } + } + + if (EFI_ERROR (Status)) { + AllChildrenStopped = FALSE; + } + } + + if (AllChildrenStopped == FALSE) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Detect whether specific FIFO is full or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is full + @retval FALSE The FIFO is not full +**/ +BOOLEAN +PciSerialFifoFull ( + IN SERIAL_DEV_FIFO *Fifo + ) +{ + if (Fifo->Surplus == 0) { + return TRUE; + } + + return FALSE; +} + +/** + Detect whether specific FIFO is empty or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is empty + @retval FALSE The FIFO is not empty +**/ +BOOLEAN +PciSerialFifoEmpty ( + IN SERIAL_DEV_FIFO *Fifo + ) +{ + if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) { + return TRUE; + } + + return FALSE; +} + +/** + Add data to specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data added to FIFO + + @retval EFI_SUCCESS Add data to specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to add data because FIFO is already full +**/ +EFI_STATUS +PciSerialFifoAdd ( + IN SERIAL_DEV_FIFO *Fifo, + IN UINT8 Data + ) +{ + /// + /// if FIFO full can not add data + /// + if (PciSerialFifoFull (Fifo)) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// FIFO is not full can add data + /// + Fifo->Data[Fifo->Last] = Data; + Fifo->Surplus--; + Fifo->Last++; + if (Fifo->Last == SERIAL_MAX_BUFFER_SIZE) { + Fifo->Last = 0; + } + + return EFI_SUCCESS; +} + +/** + Remove data from specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data removed from FIFO + + @retval EFI_SUCCESS Remove data from specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to remove data because FIFO is empty +**/ +EFI_STATUS +PciSerialFifoRemove ( + IN SERIAL_DEV_FIFO *Fifo, + OUT UINT8 *Data + ) +{ + /// + /// if FIFO is empty, no data can remove + /// + if (PciSerialFifoEmpty (Fifo)) { + return EFI_OUT_OF_RESOURCES; + } + /// + /// FIFO is not empty, can remove data + /// + *Data = Fifo->Data[Fifo->First]; + Fifo->Surplus++; + Fifo->First++; + if (Fifo->First == SERIAL_MAX_BUFFER_SIZE) { + Fifo->First = 0; + } + + return EFI_SUCCESS; +} + +/** + Reads and writes all avaliable data. + + @param[in] SerialDevice The device to flush + + @retval EFI_SUCCESS Data was read/written successfully. + @retval EFI_OUT_OF_RESOURCES Failed because software receive FIFO is full. Note, when + this happens, pending writes are not done. +**/ +EFI_STATUS +PciSerialReceiveTransmit ( + IN SERIAL_DEV *SerialDevice + ) +{ + SERIAL_PORT_LSR Lsr; + UINT8 Data; + BOOLEAN ReceiveFifoFull; + SERIAL_PORT_MSR Msr; + SERIAL_PORT_MCR Mcr; + UINTN TimeOut; + + Data = 0; + + /// + /// Begin the read or write + /// + if (SerialDevice->SoftwareLoopbackEnable) { + do { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + if (!PciSerialFifoEmpty (&SerialDevice->Transmit)) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + if (ReceiveFifoFull) { + return EFI_OUT_OF_RESOURCES; + } + + PciSerialFifoAdd (&SerialDevice->Receive, Data); + } + } while (!PciSerialFifoEmpty (&SerialDevice->Transmit)); + } else { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + do { + Lsr.Data = READ_LSR (SerialDevice->PciIo, SerialDevice->BarIndex); +#ifdef EFI_NT_EMULATOR + /// + /// This is required for NT to avoid a forever-spin... + /// This would be better if READ_LSR was a polling operation + /// that would timeout. + /// + Lsr.Bits.THRE = 1; +#endif + /// + /// Flush incomming data to prevent a an overrun during a long write + /// + if (Lsr.Bits.DR && !ReceiveFifoFull) { + ReceiveFifoFull = PciSerialFifoFull (&SerialDevice->Receive); + if (!ReceiveFifoFull) { + if (Lsr.Bits.FIFOE || Lsr.Bits.OE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) { + if (Lsr.Bits.FIFOE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) { + Data = READ_RBR (SerialDevice->PciIo, SerialDevice->BarIndex); + continue; + } + } + /// + /// Make sure the receive data will not be missed, Assert DTR + /// + if (SerialDevice->HardwareFlowControl) { + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC &= 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + + Data = READ_RBR (SerialDevice->PciIo, SerialDevice->BarIndex); + + /// + /// Deassert DTR + /// + if (SerialDevice->HardwareFlowControl) { + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + + PciSerialFifoAdd (&SerialDevice->Receive, Data); + + continue; + } + } + /// + /// Do the write + /// + if (Lsr.Bits.THRE && !PciSerialFifoEmpty (&SerialDevice->Transmit)) { + /// + /// Make sure the transmit data will not be missed + /// + if (SerialDevice->HardwareFlowControl) { + /// + /// Send RTS + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.RTS |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + /// + /// Wait for CTS + /// + TimeOut = 0; + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + while (!Msr.Bits.CTS) { + gBS->Stall (TIMEOUT_STALL_INTERVAL); + TimeOut++; + if (TimeOut > 5) { + break; + } + + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + } + + if (Msr.Bits.CTS) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + WRITE_THR (SerialDevice->PciIo, SerialDevice->BarIndex, Data); + } + } + /// + /// write the data out + /// + if (!SerialDevice->HardwareFlowControl) { + PciSerialFifoRemove (&SerialDevice->Transmit, &Data); + WRITE_THR (SerialDevice->PciIo, SerialDevice->BarIndex, Data); + } + /// + /// Make sure the transmit data will not be missed + /// + if (SerialDevice->HardwareFlowControl) { + /// + /// Assert RTS + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.RTS &= 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + } + } + } while (Lsr.Bits.THRE && !PciSerialFifoEmpty (&SerialDevice->Transmit)); + } + + return EFI_SUCCESS; +} + +/// +/// Interface Functions +/// + +/** + Reset serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + + @retval EFI_SUCCESS Reset successfully + @retval EFI_DEVICE_ERROR Failed to reset +**/ +EFI_STATUS +EFIAPI +PciSerialReset ( + IN EFI_SERIAL_IO_PROTOCOL *This + ) +{ + EFI_STATUS Status; + SERIAL_DEV *SerialDevice; + SERIAL_PORT_LCR Lcr; + SERIAL_PORT_IER Ier; + SERIAL_PORT_MCR Mcr; + SERIAL_PORT_FCR Fcr; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + /// + /// Make sure DLAB is 0. + /// + Lcr.Data = READ_LCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Lcr.Bits.DLAB = 0; + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Turn off all interrupts + /// + Ier.Data = READ_IER (SerialDevice->PciIo, SerialDevice->BarIndex); + Ier.Bits.RAVIE = 0; + Ier.Bits.THEIE = 0; + Ier.Bits.RIE = 0; + Ier.Bits.MIE = 0; + WRITE_IER (SerialDevice->PciIo, SerialDevice->BarIndex, Ier.Data); + + /// + /// Disable the FIFO. + /// + Fcr.Bits.TRFIFOE = 0; + WRITE_FCR (SerialDevice->PciIo, SerialDevice->BarIndex, Fcr.Data); + + /// + /// Turn off loopback and disable device interrupt. + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.OUT1 = 0; + Mcr.Bits.OUT2 = 0; + Mcr.Bits.LME = 0; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + /// + /// Clear the scratch pad register + /// + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0); + + /// + /// Go set the current attributes + /// + Status = This->SetAttributes ( + This, + This->Mode->BaudRate, + This->Mode->ReceiveFifoDepth, + This->Mode->Timeout, + This->Mode->Parity, + (UINT8) This->Mode->DataBits, + This->Mode->StopBits + ); + + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + /// + /// Go set the current control bits + /// + Status = This->SetControl ( + This, + This->Mode->ControlMask + ); + + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + + gBS->RestoreTPL (Tpl); + + /// + /// Device reset is complete + /// + return EFI_SUCCESS; +} + +/** + Set new attributes to a serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BaudRate The baudrate of the serial device + @param[in] ReceiveFifoDepth Fifo depth + @param[in] Timeout The request timeout for a single char + @param[in] Parity The type of parity used in serial device + @param[in] DataBits Number of databits used in serial device + @param[in] StopBits Number of stopbits used in serial device + + @retval EFI_SUCCESS The new attributes were set + @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value + @exception EFI_UNSUPPORTED Data Bits can not set to 5 or 6 + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) +**/ +EFI_STATUS +EFIAPI +PciSerialSetAttributes ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ) +{ + EFI_STATUS Status; + SERIAL_DEV *SerialDevice; + UINT32 Divisor; + UINT32 Remained; + SERIAL_PORT_LCR Lcr; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + /// + /// DEBUG ((EFI_D_ERROR, "Info: Timeout = %d\n", Timeout)); + /// + /// Increase timeout by a factor of 3 to fix character drop-out with SOL. + /// + Timeout = Timeout * 100; + + /// + /// Check for default settings and fill in actual values. + /// + if (BaudRate == 0) { + BaudRate = SERIAL_PORT_DEFAULT_BAUD_RATE; + } + + if (ReceiveFifoDepth == 0) { + ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH; + } + + if (Timeout == 0) { + Timeout = SERIAL_PORT_DEFAULT_TIMEOUT; + } + + if (Parity == DefaultParity) { + Parity = SERIAL_PORT_DEFAULT_PARITY; + } + + if (DataBits == 0) { + DataBits = SERIAL_PORT_DEFAULT_DATA_BITS; + } + + if (StopBits == DefaultStopBits) { + StopBits = SERIAL_PORT_DEFAULT_STOP_BITS; + } + /// + /// 5 and 6 data bits can not be verified on a 16550A UART + /// Return EFI_INVALID_PARAMETER if an attempt is made to use these settings. + /// + if ((DataBits == 5) || (DataBits == 6)) { + return EFI_INVALID_PARAMETER; + } + /// + /// Make sure all parameters are valid + /// + if ((BaudRate > SERIAL_PORT_MAX_BAUD_RATE) || (BaudRate < SERIAL_PORT_MIN_BAUD_RATE)) { + return EFI_INVALID_PARAMETER; + } + /// + /// 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200, + /// 38400,57600,115200 + /// + if (BaudRate < 75) { + BaudRate = 50; + } else if (BaudRate < 110) { + BaudRate = 75; + } else if (BaudRate < 134) { + BaudRate = 110; + } else if (BaudRate < 150) { + BaudRate = 134; + } else if (BaudRate < 300) { + BaudRate = 150; + } else if (BaudRate < 600) { + BaudRate = 300; + } else if (BaudRate < 1200) { + BaudRate = 600; + } else if (BaudRate < 1800) { + BaudRate = 1200; + } else if (BaudRate < 2000) { + BaudRate = 1800; + } else if (BaudRate < 2400) { + BaudRate = 2000; + } else if (BaudRate < 3600) { + BaudRate = 2400; + } else if (BaudRate < 4800) { + BaudRate = 3600; + } else if (BaudRate < 7200) { + BaudRate = 4800; + } else if (BaudRate < 9600) { + BaudRate = 7200; + } else if (BaudRate < 19200) { + BaudRate = 9600; + } else if (BaudRate < 38400) { + BaudRate = 19200; + } else if (BaudRate < 57600) { + BaudRate = 38400; + } else if (BaudRate < 115200) { + BaudRate = 57600; + } else if (BaudRate <= SERIAL_PORT_MAX_BAUD_RATE) { + BaudRate = 115200; + } + + if ((ReceiveFifoDepth < 1) || (ReceiveFifoDepth > SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH)) { + return EFI_INVALID_PARAMETER; + } + + if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) { + return EFI_INVALID_PARAMETER; + } + + if ((Parity < NoParity) || (Parity > SpaceParity)) { + return EFI_INVALID_PARAMETER; + } + + if ((DataBits < 5) || (DataBits > 8)) { + return EFI_INVALID_PARAMETER; + } + + if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) { + return EFI_INVALID_PARAMETER; + } + /// + /// for DataBits = 5, StopBits can not set TwoStopBits + /// + /// if ((DataBits == 5) && (StopBits == TwoStopBits)) { + /// return EFI_INVALID_PARAMETER; + /// } + /// + /// for DataBits = 6,7,8, StopBits can not set OneFiveStopBits + /// + if ((DataBits >= 6) && (DataBits <= 8) && (StopBits == OneFiveStopBits)) { + return EFI_INVALID_PARAMETER; + } + /// + /// See if the new attributes already match the current attributes + /// + if (SerialDevice->UartDevicePath.BaudRate == BaudRate && + SerialDevice->UartDevicePath.DataBits == DataBits && + SerialDevice->UartDevicePath.Parity == Parity && + SerialDevice->UartDevicePath.StopBits == StopBits && + SerialDevice->SerialMode.ReceiveFifoDepth == ReceiveFifoDepth && + SerialDevice->SerialMode.Timeout == Timeout + ) { + return EFI_SUCCESS; + } + /// + /// Compute divisor use to program the baud rate using a round determination + /// + Divisor = (UINT32) DivU64x32Remainder (SERIAL_PORT_INPUT_CLOCK, ((UINT32) BaudRate * 16), &Remained); + if (Remained) { + Divisor += 1; + } + + if ((Divisor == 0) || (Divisor & 0xffff0000)) { + return EFI_INVALID_PARAMETER; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + /// + /// Compute the actual baud rate that the serial port will be programmed for. + /// + BaudRate = SERIAL_PORT_INPUT_CLOCK / Divisor / 16; + + /// + /// Put serial port on Divisor Latch Mode + /// + Lcr.Data = READ_LCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Lcr.Bits.DLAB = 1; + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Write the divisor to the serial port + /// + WRITE_DLL (SerialDevice->PciIo, SerialDevice->BarIndex, (UINT8) (Divisor & 0xff)); + WRITE_DLM (SerialDevice->PciIo, SerialDevice->BarIndex, (UINT8) ((Divisor >> 8) & 0xff)); + + /// + /// Put serial port back in normal mode and set remaining attributes. + /// + Lcr.Bits.DLAB = 0; + + switch (Parity) { + case NoParity: + Lcr.Bits.PAREN = 0; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 0; + break; + + case EvenParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 1; + Lcr.Bits.STICPAR = 0; + break; + + case OddParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 0; + break; + + case SpaceParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 1; + Lcr.Bits.STICPAR = 1; + break; + + case MarkParity: + Lcr.Bits.PAREN = 1; + Lcr.Bits.EVENPAR = 0; + Lcr.Bits.STICPAR = 1; + break; + default: + break; + } + + switch (StopBits) { + case OneStopBit: + Lcr.Bits.STOPB = 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + Lcr.Bits.STOPB = 1; + break; + default: + break; + } + /// + /// DataBits + /// + Lcr.Bits.SERIALDB = (UINT8) ((DataBits - 5) & 0x03); + WRITE_LCR (SerialDevice->PciIo, SerialDevice->BarIndex, Lcr.Data); + + /// + /// Set the Serial I/O mode + /// + This->Mode->BaudRate = BaudRate; + This->Mode->ReceiveFifoDepth = ReceiveFifoDepth; + This->Mode->Timeout = Timeout; + This->Mode->Parity = Parity; + This->Mode->DataBits = DataBits; + This->Mode->StopBits = StopBits; + + /// + /// See if Device Path Node has actually changed + /// + if (SerialDevice->UartDevicePath.BaudRate == BaudRate && + SerialDevice->UartDevicePath.DataBits == DataBits && + SerialDevice->UartDevicePath.Parity == Parity && + SerialDevice->UartDevicePath.StopBits == StopBits + ) { + gBS->RestoreTPL (Tpl); + return EFI_SUCCESS; + } + /// + /// Update the device path + /// + SerialDevice->UartDevicePath.BaudRate = BaudRate; + SerialDevice->UartDevicePath.DataBits = DataBits; + SerialDevice->UartDevicePath.Parity = (UINT8) Parity; + SerialDevice->UartDevicePath.StopBits = (UINT8) StopBits; + + NewDevicePath = AppendDevicePathNode ( + SerialDevice->ParentDevicePath, + (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath + ); + if (NewDevicePath == NULL) { + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + + if (SerialDevice->Handle != NULL) { + Status = gBS->ReinstallProtocolInterface ( + SerialDevice->Handle, + &gEfiDevicePathProtocolGuid, + SerialDevice->DevicePath, + NewDevicePath + ); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (Tpl); + return Status; + } + } + + if (SerialDevice->DevicePath) { + FreePool (SerialDevice->DevicePath); + } + + SerialDevice->DevicePath = NewDevicePath; + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Set ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control bits that can be settable + + @retval EFI_SUCCESS New Control bits were set successfully + @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported +**/ +EFI_STATUS +EFIAPI +PciSerialSetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ) +{ + SERIAL_DEV *SerialDevice; + SERIAL_PORT_MCR Mcr; + EFI_TPL Tpl; + + /// + /// The control bits that can be set are : + /// EFI_SERIAL_DATA_TERMINAL_READY: 0x0001 // WO + /// EFI_SERIAL_REQUEST_TO_SEND: 0x0002 // WO + /// EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000 // RW + /// EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000 // RW + /// + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + /// + /// first determine the parameter is invalid + /// + if (Control & 0xffff8ffc) { + return EFI_UNSUPPORTED; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC = 0; + Mcr.Bits.RTS = 0; + Mcr.Bits.LME = 0; + SerialDevice->SoftwareLoopbackEnable = FALSE; + SerialDevice->HardwareFlowControl = FALSE; + + if (Control & EFI_SERIAL_DATA_TERMINAL_READY) { + Mcr.Bits.DTRC = 1; + } + + if (Control & EFI_SERIAL_REQUEST_TO_SEND) { + Mcr.Bits.RTS = 1; + } + + if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) { + Mcr.Bits.LME = 1; + } + + if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) { + SerialDevice->HardwareFlowControl = TRUE; + } + + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) { + SerialDevice->SoftwareLoopbackEnable = TRUE; + } + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Get ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control signals of the serial device + + @retval EFI_SUCCESS Get Control signals successfully +**/ +EFI_STATUS +EFIAPI +PciSerialGetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ) +{ + SERIAL_DEV *SerialDevice; + SERIAL_PORT_MSR Msr; + SERIAL_PORT_MCR Mcr; + EFI_TPL Tpl; + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + + *Control = 0; + + /// + /// Read the Modem Status Register + /// + Msr.Data = READ_MSR (SerialDevice->PciIo, SerialDevice->BarIndex); + + if (Msr.Bits.CTS) { + *Control |= EFI_SERIAL_CLEAR_TO_SEND; + } + + if (Msr.Bits.DSR) { + *Control |= EFI_SERIAL_DATA_SET_READY; + } + + if (Msr.Bits.RI) { + *Control |= EFI_SERIAL_RING_INDICATE; + } + + if (Msr.Bits.DCD) { + *Control |= EFI_SERIAL_CARRIER_DETECT; + } + /// + /// Read the Modem Control Register + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + + if (Mcr.Bits.DTRC) { + *Control |= EFI_SERIAL_DATA_TERMINAL_READY; + } + + if (Mcr.Bits.RTS) { + *Control |= EFI_SERIAL_REQUEST_TO_SEND; + } + + if (Mcr.Bits.LME) { + *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE; + } + + if (SerialDevice->HardwareFlowControl) { + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + /// + /// See if the Transmit FIFO is empty + /// + PciSerialReceiveTransmit (SerialDevice); + + if (PciSerialFifoEmpty (&SerialDevice->Transmit)) { + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + /// + /// See if the Receive FIFO is empty. + /// + PciSerialReceiveTransmit (SerialDevice); + + if (PciSerialFifoEmpty (&SerialDevice->Receive)) { + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + if (SerialDevice->SoftwareLoopbackEnable) { + *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; + } + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Write the specified number of bytes to serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data actually written + @param[in] Buffer The buffer of data to write + + @retval EFI_SUCCESS The data were written successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The write operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialWrite ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + SERIAL_DEV *SerialDevice; + UINT8 *CharBuffer; + UINT32 Index; + UINTN Elapsed; + UINTN ActualWrite; + EFI_TPL Tpl; + SERIAL_PORT_MCR Mcr; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + Elapsed = 0; + ActualWrite = 0; + + if (*BufferSize == 0) { + return EFI_SUCCESS; + } + + if (!Buffer) { + return EFI_DEVICE_ERROR; + } + + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + CharBuffer = (UINT8 *) Buffer; + + for (Index = 0; Index < *BufferSize; Index++) { + PciSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]); + + while + ( + PciSerialReceiveTransmit (SerialDevice) != EFI_SUCCESS || + PciSerialFifoEmpty (&SerialDevice->Transmit) == FALSE + ) { + /// + /// Unsuccessful write so check if timeout has expired, if not, + /// stall for a bit, increment time elapsed, and try again + /// + if (Elapsed >= This->Mode->Timeout) { + *BufferSize = ActualWrite; + if (PciSerialFifoEmpty (&SerialDevice->Transmit)) { + gBS->RestoreTPL (Tpl); + return EFI_TIMEOUT; + } + } + + gBS->Stall (TIMEOUT_STALL_INTERVAL); + + Elapsed += TIMEOUT_STALL_INTERVAL; + } // end while + ActualWrite++; + /// + /// Successful write so reset timeout + /// + Elapsed = 0; + + } // end for + /// + /// FW expects DTR bit to be SET before sending data. So enable DTR bit always. + /// + Mcr.Data = READ_MCR (SerialDevice->PciIo, SerialDevice->BarIndex); + Mcr.Bits.DTRC |= 1; + WRITE_MCR (SerialDevice->PciIo, SerialDevice->BarIndex, Mcr.Data); + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Read the specified number of bytes from serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data returned in buffer + @param[in] Buffer The buffer to return the data into + + @retval EFI_SUCCESS The data were read successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The read operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialRead ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + SERIAL_DEV *SerialDevice; + UINT32 Index; + UINT8 *CharBuffer; + UINTN Elapsed; + EFI_STATUS Status; + EFI_TPL Tpl; + + SerialDevice = SERIAL_DEV_FROM_THIS (This); + Elapsed = 0; + + if (*BufferSize == 0) { + return EFI_SUCCESS; + } + + if (!Buffer) { + return EFI_DEVICE_ERROR; + } + /// + /// SerialDevice->Receive.First = 0; + /// SerialDevice->Receive.Last = 0; + /// SerialDevice->Receive.Surplus = SERIAL_MAX_BUFFER_SIZE; + /// + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + Status = PciSerialReceiveTransmit (SerialDevice); + + if (EFI_ERROR (Status)) { + *BufferSize = 0; + + gBS->RestoreTPL (Tpl); + + return EFI_DEVICE_ERROR; + } + + CharBuffer = (UINT8 *) Buffer; + for (Index = 0; Index < *BufferSize; Index++) { + while (PciSerialFifoRemove (&SerialDevice->Receive, &(CharBuffer[Index])) != EFI_SUCCESS) { + /// + /// Unsuccessful read so check if timeout has expired, if not, + /// stall for a bit, increment time elapsed, and try again + /// Need this time out to get conspliter to work. + /// + if (Elapsed >= This->Mode->Timeout) { + *BufferSize = Index; + gBS->RestoreTPL (Tpl); + return EFI_TIMEOUT; + } + + gBS->Stall (TIMEOUT_STALL_INTERVAL); + Elapsed += TIMEOUT_STALL_INTERVAL; + + Status = PciSerialReceiveTransmit (SerialDevice); + if (Status == EFI_DEVICE_ERROR) { + *BufferSize = Index; + gBS->RestoreTPL (Tpl); + return EFI_DEVICE_ERROR; + } + } // end while + /// + /// Successful read so reset timeout + /// + Elapsed = 0; + } // end for + PciSerialReceiveTransmit (SerialDevice); + + gBS->RestoreTPL (Tpl); + + return EFI_SUCCESS; +} + +/** + Check serial port status. + + @param[in] SerialDevice The serial device instance + + @retval True It is present. + @retval False No present. +**/ +BOOLEAN +PciSerialPortPresent ( + IN SERIAL_DEV *SerialDevice + ) +{ + UINT8 Temp; + BOOLEAN Status; + + Status = TRUE; + + /// + /// Save SCR reg + /// + Temp = READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex); + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0xAA); + + if (READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex) != 0xAA) { +#ifndef EFI_NT_EMULATOR + Status = FALSE; +#endif + } + + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, 0x55); + + if (READ_SCR (SerialDevice->PciIo, SerialDevice->BarIndex) != 0x55) { +#ifndef EFI_NT_EMULATOR + Status = FALSE; +#endif + } + /// + /// Restore SCR + /// + WRITE_SCR (SerialDevice->PciIo, SerialDevice->BarIndex, Temp); + return Status; +} + +/** + PCI I/O read for byte only + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + + @retval Return value read +**/ +UINT8 +PciSerialReadPort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset + ) +{ + UINT8 Data; + + /// + /// Use PciIo to access IO + /// + PciIo->Io.Read ( + PciIo, + EfiPciIoWidthUint8, + (UINT8) BarIndex, + (UINT16) Offset, + (UINTN) 1, + &Data + ); + return Data; +} + +/** + PCI I/O - write a byte + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + @param[in] Data Written value +**/ +VOID +PciSerialWritePort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset, + IN UINT8 Data + ) +{ + /// + /// Use PciIo to access IO + /// + PciIo->Io.Write ( + PciIo, + EfiPciIoWidthUint8, + (UINT8) BarIndex, + (UINT16) Offset, + (UINTN) 1, + &Data + ); +} + +/** + Sol driver entry + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif new file mode 100644 index 0000000..950205e --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.cif @@ -0,0 +1,13 @@ +<component> + name = "PciSerial" + category = ModulePart + LocalRoot = "ReferenceCode\ME\ActiveManagement\Sol\Dxe\" + RefName = "PciSerial" +[files] +"PciSerial.sdl" +"PciSerial.mak" +"PciSerial.c" +"ComponentName.c" +"PciSerial.h" +"PciSerial.inf" +<endComponent> diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h new file mode 100644 index 0000000..320de88 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.h @@ -0,0 +1,787 @@ +/** @file + Include for Pci Serial Driver + +@copyright + Copyright (c) 2004 - 2012 Intel Corporation. All rights + reserved This software and associated documentation (if any) + is furnished under a license and may only be used or copied in + accordance with the terms of the license. Except as permitted + by such license, no part of this software or documentation may + be reproduced, stored in a retrieval system, or transmitted in + any form or by any means without the express written consent + of Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#ifndef _PCI_SERIAL_H +#define _PCI_SERIAL_H +#include "Pci22.h" +#include "Acpi.h" +#include "AmtLib.h" + +// +// Driver Consumed Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (PciIo) +#include EFI_PROTOCOL_DEFINITION (DevicePath) +#include EFI_PROTOCOL_CONSUMER (PciRootBridgeIo) + +// +// Driver Produced Protocol Prototypes +// +#include EFI_PROTOCOL_DEFINITION (DriverBinding) +#include EFI_PROTOCOL_DEFINITION (ComponentName) +#include EFI_PROTOCOL_DEFINITION (SerialIo) + +// +// Status code GUID +// +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) + +// +// Internal Data Structures +// +#define SERIAL_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'e', 'r', 'd') +#define SERIAL_MAX_BUFFER_SIZE 16 +#define TIMEOUT_STALL_INTERVAL 300 + +/// +/// Name: SERIAL_DEV_FIFO +/// Purpose: To define Receive FIFO and Transmit FIFO +/// Context: Used by serial data transmit and receive +/// Fields: +/// First UINT32: The index of the first data in array Data[] +/// Last UINT32: The index, which you can put a new data into array Data[] +/// Surplus UINT32: Identify how many data you can put into array Data[] +/// Data[] UINT8 : An array, which used to store data +/// +typedef struct { + UINT32 First; + UINT32 Last; + UINT32 Surplus; + UINT8 Data[SERIAL_MAX_BUFFER_SIZE]; +} SERIAL_DEV_FIFO; + +typedef enum { + UART8250 = 0, + UART16450 = 1, + UART16550 = 2, + UART16550A= 3 +} EFI_UART_TYPE; + +/// +/// Name: SERIAL_DEV +/// Purpose: To provide device specific information +/// Context: +/// Fields: +/// Signature UINTN: The identity of the serial device +/// SerialIo SERIAL_IO_PROTOCOL: Serial I/O protocol interface +/// SerialMode SERIAL_IO_MODE: +/// DevicePath EFI_DEVICE_PATH_PROTOCOL *: Device path of the serial device +/// Handle EFI_HANDLE: The handle instance attached to serial device +/// BarIndex UINT16: The bar index in pci cfg space that contains the base address +/// of specific serial device +/// Receive SERIAL_DEV_FIFO: The FIFO used to store data, +/// which is received by UART +/// Transmit SERIAL_DEV_FIFO: The FIFO used to store data, +/// which you want to transmit by UART +/// SoftwareLoopbackEnable BOOLEAN: +/// Type EFI_UART_TYPE: Specify the UART type of certain serial device +/// +typedef struct { + UINTN Signature; + + EFI_HANDLE Handle; + EFI_SERIAL_IO_PROTOCOL SerialIo; + EFI_SERIAL_IO_MODE SerialMode; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + UART_DEVICE_PATH UartDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + + UINT16 BarIndex; + SERIAL_DEV_FIFO Receive; + SERIAL_DEV_FIFO Transmit; + BOOLEAN SoftwareLoopbackEnable; + BOOLEAN HardwareFlowControl; + EFI_UART_TYPE Type; + EFI_UNICODE_STRING_TABLE *ControllerNameTable; +} SERIAL_DEV; + +#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE) + +// +// Globale Variables +// +extern EFI_DRIVER_BINDING_PROTOCOL mPciSerialControllerDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL mPciSerialComponentName; + +// +// Serial Driver Defaults +// +#define SERIAL_PORT_DEFAULT_BAUD_RATE 115200 +#define SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH 1 +#define SERIAL_PORT_DEFAULT_TIMEOUT 1000000 ///< 1 seconds +#define SERIAL_PORT_DEFAULT_PARITY NoParity +#define SERIAL_PORT_DEFAULT_DATA_BITS 8 +#define SERIAL_PORT_DEFAULT_STOP_BITS 1 +#define SERIAL_PORT_DEFAULT_CONTROL_MASK EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE + +/// +/// (24000000/13)MHz input clock +/// +#define SERIAL_PORT_INPUT_CLOCK 1843200 + +/// +/// 115200 baud with rounding errors +/// +#define SERIAL_PORT_MAX_BAUD_RATE 115400 +#define SERIAL_PORT_MIN_BAUD_RATE 50 + +#define SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH 16 +#define SERIAL_PORT_MIN_TIMEOUT 1 ///< 1 uS +#define SERIAL_PORT_MAX_TIMEOUT 10000000000 ///< 10000 seconds +// +// UART Registers +// +#define SERIAL_REGISTER_THR 0 ///< WO Transmit Holding Register +#define SERIAL_REGISTER_RBR 0 ///< RO Receive Buffer Register +#define SERIAL_REGISTER_DLL 0 ///< R/W Divisor Latch LSB +#define SERIAL_REGISTER_DLM 1 ///< R/W Divisor Latch MSB +#define SERIAL_REGISTER_IER 1 ///< R/W Interrupt Enable Register +#define SERIAL_REGISTER_IIR 2 ///< RO Interrupt Identification Register +#define SERIAL_REGISTER_FCR 2 ///< WO FIFO Cotrol Register +#define SERIAL_REGISTER_LCR 3 ///< R/W Line Control Register +#define SERIAL_REGISTER_MCR 4 ///< R/W Modem Control Register +#define SERIAL_REGISTER_LSR 5 ///< R/W Line Status Register +#define SERIAL_REGISTER_MSR 6 ///< R/W Modem Status Register +#define SERIAL_REGISTER_SCR 7 ///< R/W Scratch Pad Register +#define TEKOA_SOL_VENDOR_ID 0x8086 +#define TEKOA_SOL_DEVICE_ID 0x108F + +#define PCI_CLASS_SCC 0x07 +#define PCI_SUBCLASS_SERIAL 0x00 +#define PCI_IF_GENERIC_XT 0x00 +#define PCI_IF_16450 0x01 +#define PCI_IF_16550 0x02 +#define PCI_IF_16650 0x03 +#define PCI_IF_16750 0x04 +#define PCI_IF_16850 0x05 +#define PCI_IF_16950 0x06 +#define PCI_SUBCLASS_PARALLEL 0x01 +#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02 +#define PCI_SUBCLASS_MODEM 0x03 +#define PCI_SUBCLASS_OTHER 0x80 + +#pragma pack(1) +/// +/// Name: SERIAL_PORT_IER_BITS +/// Purpose: Define each bit in Interrupt Enable Register +/// Context: +/// Fields: +/// RAVIE Bit0: Receiver Data Available Interrupt Enable +/// THEIE Bit1: Transmistter Holding Register Empty Interrupt Enable +/// RIE Bit2: Receiver Interrupt Enable +/// MIE Bit3: Modem Interrupt Enable +/// Reserved Bit4-Bit7: Reserved +/// +typedef struct { + UINT8 RAVIE : 1; + UINT8 THEIE : 1; + UINT8 RIE : 1; + UINT8 MIE : 1; + UINT8 Reserved : 4; +} SERIAL_PORT_IER_BITS; + +/// +/// Name: SERIAL_PORT_IER +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_IER_BITS: Bits of the IER +/// Data UINT8: the value of the IER +/// +typedef union { + SERIAL_PORT_IER_BITS Bits; + UINT8 Data; +} SERIAL_PORT_IER; + +/// +/// Name: SERIAL_PORT_IIR_BITS +/// Purpose: Define each bit in Interrupt Identification Register +/// Context: +/// Fields: +/// IPS Bit0: Interrupt Pending Status +/// IIB Bit1-Bit3: Interrupt ID Bits +/// Reserved Bit4-Bit5: Reserved +/// FIFOES Bit6-Bit7: FIFO Mode Enable Status +/// +typedef struct { + UINT8 IPS : 1; + UINT8 IIB : 3; + UINT8 Reserved : 2; + UINT8 FIFOES : 2; +} SERIAL_PORT_IIR_BITS; + +/// +/// Name: SERIAL_PORT_IIR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_IIR_BITS: Bits of the IIR +/// Data UINT8: the value of the IIR +/// +typedef union { + SERIAL_PORT_IIR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_IIR; + +/// +/// Name: SERIAL_PORT_FCR_BITS +/// Purpose: Define each bit in FIFO Control Register +/// Context: +/// Fields: +/// TRFIFOE Bit0: Transmit and Receive FIFO Enable +/// RESETRF Bit1: Reset Reciever FIFO +/// RESETTF Bit2: Reset Transmistter FIFO +/// DMS Bit3: DMA Mode Select +/// Reserved Bit4-Bit5: Reserved +/// RTB Bit6-Bit7: Receive Trigger Bits +/// +typedef struct { + UINT8 TRFIFOE : 1; + UINT8 RESETRF : 1; + UINT8 RESETTF : 1; + UINT8 DMS : 1; + UINT8 Reserved : 2; + UINT8 RTB : 2; +} SERIAL_PORT_FCR_BITS; + +/// +/// Name: SERIAL_PORT_FCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_FCR_BITS: Bits of the FCR +/// Data UINT8: the value of the FCR +/// +typedef union { + SERIAL_PORT_FCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_FCR; + +/// +/// Name: SERIAL_PORT_LCR_BITS +/// Purpose: Define each bit in Line Control Register +/// Context: +/// Fields: +/// SERIALDB Bit0-Bit1: Number of Serial Data Bits +/// STOPB Bit2: Number of Stop Bits +/// PAREN Bit3: Parity Enable +/// EVENPAR Bit4: Even Parity Select +/// STICPAR Bit5: Sticky Parity +/// BRCON Bit6: Break Control +/// DLAB Bit7: Divisor Latch Access Bit +/// +typedef struct { + UINT8 SERIALDB : 2; + UINT8 STOPB : 1; + UINT8 PAREN : 1; + UINT8 EVENPAR : 1; + UINT8 STICPAR : 1; + UINT8 BRCON : 1; + UINT8 DLAB : 1; +} SERIAL_PORT_LCR_BITS; + +/// +/// Name: SERIAL_PORT_LCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_LCR_BITS: Bits of the LCR +/// Data UINT8: the value of the LCR +/// +typedef union { + SERIAL_PORT_LCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_LCR; + +/// +/// Name: SERIAL_PORT_MCR_BITS +/// Purpose: Define each bit in Modem Control Register +/// Context: +/// Fields: +/// DTRC Bit0: Data Terminal Ready Control +/// RTS Bit1: Request To Send Control +/// OUT1 Bit2: Output1 +/// OUT2 Bit3: Output2, used to disable interrupt +/// LME; Bit4: Loopback Mode Enable +/// Reserved Bit5-Bit7: Reserved +/// +typedef struct { + UINT8 DTRC : 1; + UINT8 RTS : 1; + UINT8 OUT1 : 1; + UINT8 OUT2 : 1; + UINT8 LME : 1; + UINT8 Reserved : 3; +} SERIAL_PORT_MCR_BITS; + +/// +/// Name: SERIAL_PORT_MCR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_MCR_BITS: Bits of the MCR +/// Data UINT8: the value of the MCR +/// +typedef union { + SERIAL_PORT_MCR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_MCR; + +/// +/// Name: SERIAL_PORT_LSR_BITS +/// Purpose: Define each bit in Line Status Register +/// Context: +/// Fields: +/// DR Bit0: Receiver Data Ready Status +/// OE Bit1: Overrun Error Status +/// PE Bit2: Parity Error Status +/// FE Bit3: Framing Error Status +/// BI Bit4: Break Interrupt Status +/// THRE Bit5: Transmistter Holding Register Status +/// TEMT Bit6: Transmitter Empty Status +/// FIFOE Bit7: FIFO Error Status +/// +typedef struct { + UINT8 DR : 1; + UINT8 OE : 1; + UINT8 PE : 1; + UINT8 FE : 1; + UINT8 BI : 1; + UINT8 THRE : 1; + UINT8 TEMT : 1; + UINT8 FIFOE : 1; +} SERIAL_PORT_LSR_BITS; + +/// +/// Name: SERIAL_PORT_LSR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_LSR_BITS: Bits of the LSR +/// Data UINT8: the value of the LSR +/// +typedef union { + SERIAL_PORT_LSR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_LSR; + +/// +/// Name: SERIAL_PORT_MSR_BITS +/// Purpose: Define each bit in Modem Status Register +/// Context: +/// Fields: +/// DeltaCTS Bit0: Delta Clear To Send Status +/// DeltaDSR Bit1: Delta Data Set Ready Status +/// TrailingEdgeRI Bit2: Trailing Edge of Ring Indicator Status +/// DeltaDCD Bit3: Delta Data Carrier Detect Status +/// CTS Bit4: Clear To Send Status +/// DSR Bit5: Data Set Ready Status +/// RI Bit6: Ring Indicator Status +/// DCD Bit7: Data Carrier Detect Status +/// +typedef struct { + UINT8 DeltaCTS : 1; + UINT8 DeltaDSR : 1; + UINT8 TrailingEdgeRI : 1; + UINT8 DeltaDCD : 1; + UINT8 CTS : 1; + UINT8 DSR : 1; + UINT8 RI : 1; + UINT8 DCD : 1; +} SERIAL_PORT_MSR_BITS; + +/// +/// Name: SERIAL_PORT_MSR +/// Purpose: +/// Context: +/// Fields: +/// Bits SERIAL_PORT_MSR_BITS: Bits of the MSR +/// Data UINT8: the value of the MSR +/// +typedef union { + SERIAL_PORT_MSR_BITS Bits; + UINT8 Data; +} SERIAL_PORT_MSR; + +#pragma pack() +// +// Define serial register I/O macros +// +#define READ_RBR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_RBR) +#define READ_DLL(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_DLL) +#define READ_DLM(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_DLM) +#define READ_IER(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_IER) +#define READ_IIR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_IIR) +#define READ_LCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_LCR) +#define READ_MCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_MCR) +#define READ_LSR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_LSR) +#define READ_MSR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_MSR) +#define READ_SCR(IO, B) PciSerialReadPort (IO, B, SERIAL_REGISTER_SCR) + +#define WRITE_THR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_THR, D) +#define WRITE_DLL(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_DLL, D) +#define WRITE_DLM(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_DLM, D) +#define WRITE_IER(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_IER, D) +#define WRITE_FCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_FCR, D) +#define WRITE_LCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_LCR, D) +#define WRITE_MCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_MCR, D) +#define WRITE_LSR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_LSR, D) +#define WRITE_MSR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_MSR, D) +#define WRITE_SCR(IO, B, D) PciSerialWritePort (IO, B, SERIAL_REGISTER_SCR, D) + +#define PCI_SERIAL_PORT_NAME "PCI Serial Port # " + +#define R_PCI_SVID 0x2C + +/** + This function checks to see if the driver supports a device specified by + "Controller handle" parameter. It is called by DXE Core StartImage() or + ConnectController() routines. The driver uses 'device path' and/or + 'services' from the Bus I/O abstraction attached to the controller handle + to determine if the driver support this controller handle. + + Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all + devices (or, controller) and assigns GUIDs to them. + + @param[in] This a pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. + @param[in] RemainingDevicePath A pointer to the device path. Ignored by device + driver but used by bus driver + + @retval EFI_SUCCESS Have device to support + @retval EFI_NOT_FOUND The device doesn't support or relative environment not ready +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + This routine is called right after the .Supported() called + and return EFI_SUCCESS. Notes: The supported protocols are + checked but the Protocols are closed. + + @param[in] This A pointer points to the Binding Protocol instance + @param[in] Controller The handle of controller to be tested. Parameter + passed by the caller + @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by + device driver + + @retval EFI_SUCCESS The driver ready and initial complete. + @retval Other The device doesn't initial. +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +; + +/** + Stop. + + @param[in] This Pointer to driver binding protocol + @param[in] Controller Controller handle to connect + @param[in] NumberOfChildren Number of children handle created by this driver + @param[in] ChildHandleBuffer Buffer containing child handle created + + @retval EFI_SUCCESS Driver disconnected successfully from controller + @retval EFI_DEVICE_ERROR Cannot find BIOS_VIDEO_DEV structure +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +; + +/** + Detect whether specific FIFO is full or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is full + @retval FALSE The FIFO is not full +**/ +BOOLEAN +PciSerialFifoFull ( + IN SERIAL_DEV_FIFO *Fifo + ) +; + +/** + Detect whether specific FIFO is empty or not + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + + @retval TRUE The FIFO is empty + @retval FALSE The FIFO is not empty +**/ +BOOLEAN +PciSerialFifoEmpty ( + IN SERIAL_DEV_FIFO *Fifo + ) +; + +/** + Add data to specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data added to FIFO + + @retval EFI_SUCCESS Add data to specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to add data because FIFO is already full +**/ +EFI_STATUS +PciSerialFifoAdd ( + IN SERIAL_DEV_FIFO *Fifo, + IN UINT8 Data + ) +; + +/** + Remove data from specific FIFO + + @param[in] Fifo A pointer to the Data Structure SERIAL_DEV_FIFO + @param[in] Data The data removed from FIFO + + @retval EFI_SUCCESS Remove data from specific FIFO successfully + @retval EFI_OUT_OF_RESOURCES Failed to remove data because FIFO is empty +**/ +EFI_STATUS +PciSerialFifoRemove ( + IN SERIAL_DEV_FIFO *Fifo, + OUT UINT8 *Data + ) +; + +/** + Reads and writes all avaliable data. + + @param[in] SerialDevice The device to flush + + @retval EFI_SUCCESS Data was read/written successfully. + @retval EFI_OUT_OF_RESOURCES Failed because software receive FIFO is full. Note, when + this happens, pending writes are not done. +**/ +EFI_STATUS +PciSerialReceiveTransmit ( + IN SERIAL_DEV *SerialDevice + ) +; +/// +/// Serial I/O Protocol Interface +/// +/** + Reset serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + + @retval EFI_SUCCESS Reset successfully + @retval EFI_DEVICE_ERROR Failed to reset +**/ +EFI_STATUS +EFIAPI +PciSerialReset ( + IN EFI_SERIAL_IO_PROTOCOL *This + ) +; + +/** + Set new attributes to a serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BaudRate The baudrate of the serial device + @param[in] ReceiveFifoDepth Fifo depth + @param[in] Timeout The request timeout for a single char + @param[in] Parity The type of parity used in serial device + @param[in] DataBits Number of databits used in serial device + @param[in] StopBits Number of stopbits used in serial device + + @retval EFI_SUCCESS The new attributes were set + @retval EFI_INVALID_PARAMETERS One or more attributes have an unsupported value + @exception EFI_UNSUPPORTED Data Bits can not set to 5 or 6 + @retval EFI_DEVICE_ERROR The serial device is not functioning correctly (no return) +**/ +EFI_STATUS +EFIAPI +PciSerialSetAttributes ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT64 BaudRate, + IN UINT32 ReceiveFifoDepth, + IN UINT32 Timeout, + IN EFI_PARITY_TYPE Parity, + IN UINT8 DataBits, + IN EFI_STOP_BITS_TYPE StopBits + ) +; + +/** + Set ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control bits that can be settable + + @retval EFI_SUCCESS New Control bits were set successfully + @retval EFI_UNSUPPORTED The Control bits wanted to set are not supported +**/ +EFI_STATUS +EFIAPI +PciSerialSetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN UINT32 Control + ) +; + +/** + Get ControlBits + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] Control Control signals of the serial device + + @retval EFI_SUCCESS Get Control signals successfully +**/ +EFI_STATUS +EFIAPI +PciSerialGetControl ( + IN EFI_SERIAL_IO_PROTOCOL *This, + OUT UINT32 *Control + ) +; + +/** + Write the specified number of bytes to serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data actually written + @param[in] Buffer The buffer of data to write + + @retval EFI_SUCCESS The data were written successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The write operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialWrite ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +; + +/** + Read the specified number of bytes from serial device + + @param[in] This Pointer to EFI_SERIAL_IO_PROTOCOL + @param[in] BufferSize On input the size of Buffer, on output the amount of data returned in buffer + @param[in] Buffer The buffer to return the data into + + @retval EFI_SUCCESS The data were read successfully + @retval EFI_DEVICE_ERROR The device reported an error + @retval EFI_TIMEOUT The read operation was stopped due to timeout +**/ +EFI_STATUS +EFIAPI +PciSerialRead ( + IN EFI_SERIAL_IO_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +; + +/// +/// Internal Functions +/// +/** + Check serial port status. + + @param[in] SerialDevice The serial device instance + + @retval True It is present. + @retval False No present. +**/ +BOOLEAN +PciSerialPortPresent ( + IN SERIAL_DEV *SerialDevice + ) +; + +/** + PCI I/O read for byte only + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + + @retval Return value read +**/ +UINT8 +PciSerialReadPort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset + ) +; + +/** + PCI I/O - write a byte + + @param[in] PciIo Pointer of Pci IO protocol + @param[in] BarIndex Index of the BAR within PCI device + @param[in] Offset Offset of the BARIndex within PCI device + @param[in] Data Written value +**/ +VOID +PciSerialWritePort ( + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN UINT16 BarIndex, + IN UINT16 Offset, + IN UINT8 Data + ) +; + +/** + Sol driver entry + + @param[in] ImageHandle Handle for this drivers loaded image protocol. + @param[in] SystemTable EFI system table. + + @retval EFI_SUCCESS Always return EFI_SUCCESS +**/ +EFI_STATUS +EFIAPI +PciSerialControllerDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; +#endif diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf new file mode 100644 index 0000000..a3b4e0b --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.inf @@ -0,0 +1,87 @@ +## @file +# Component description file for PciSerial module. +# +#@copyright +# Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + +[defines] +BASE_NAME = PciSerial +FILE_GUID = FB142B99-DF57-46cb-BC69-0BF858A734F9 +COMPONENT_TYPE = BS_DRIVER + +[sources.common] + PciSerial.c + PciSerial.h + ComponentName.c + +# +# Edk II Glue Driver Entry Point +# + EdkIIGlueDxeDriverEntryPoint.c + +[includes.common] + $(EFI_SOURCE)/$(PROJECT_ME_ROOT) + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Dxe + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/AMT/Include + $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + +# +# EDK II Glue Library utilizes some standard headers from EDK +# + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Efi + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Framework/Include + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include + +[libraries.common] + AmtLib + EdkProtocolLib + EdkIIGlueBaseLib + EdkIIGlueBaseMemoryLib + EdkIIGlueDxeReportStatusCodeLib + EdkIIGlueDxeDebugLibReportStatusCode + EdkIIGlueUefiBootServicesTableLib + EdkIIGlueUefiRuntimeServicesTableLib + EdkIIGlueUefiDevicePathLib + EdkIIGlueUefiLib + EdkIIGlueUefiDriverModelLib + +[nmake.common] + IMAGE_ENTRY_POINT = _ModuleEntryPoint + +# +# Module Entry Point +# + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PciSerialControllerDriverEntryPoint \ + -D __EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mPciSerialControllerDriverBinding \ + -D __EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mPciSerialComponentName + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \ + -D __EDKII_GLUE_BASE_MEMORY_LIB__ \ + -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \ + -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ + C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_UEFI_LIB__ \ + -D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak new file mode 100644 index 0000000..a94fda5 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.mak @@ -0,0 +1,55 @@ +# MAK file for the ModulePart:PciSerial + +all : PciSerial + +$(BUILD_DIR)\PciSerial.mak : $(PciSerial_DIR)\$(@B).cif $(PciSerial_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PciSerial_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PciSerial : $(BUILD_DIR)\PciSerial.mak PciSerialBin + +PciSerial_INCLUDES=\ + $(EdkIIGlueLib_INCLUDES)\ + $(ME_INCLUDES)\ + $(INTEL_PCH_INCLUDES) + +PciSerial_LIBS=\ + $(EDKPROTOCOLLIB)\ + $(AmtLibDxe_LIB)\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + $(EdkIIGlueBaseMemoryLib_LIB)\ + $(EdkIIGlueDxeReportStatusCodeLib_LIB)\ + $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\ + $(EdkIIGlueUefiBootServicesTableLib_LIB)\ + $(EdkIIGlueUefiDevicePathLib_LIB)\ + $(EdkIIGlueUefiLib_LIB)\ + $(EdkIIGlueUefiDriverModelLib_LIB)\ + +PciSerial_DEFINES=\ + $(MY_DEFINES)\ + /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PciSerialControllerDriverEntryPoint"\ + /D"__EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mPciSerialControllerDriverBinding"\ + /D"__EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mPciSerialComponentName"\ + /D __EDKII_GLUE_BASE_LIB__\ + /D __EDKII_GLUE_BASE_MEMORY_LIB__\ + /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \ + /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ + /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\ + /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__\ + /D __EDKII_GLUE_UEFI_LIB__ \ + /D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ + +PciSerialBin : $(PciSerial_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PciSerial.mak all \ + "MY_INCLUDES=$(PciSerial_INCLUDES)"\ + "MY_DEFINES=$(PciSerial_DEFINES)"\ + GUID=FB142B99-DF57-46cb-BC69-0BF858A734F9 \ + ENTRY_POINT=_ModuleEntryPoint \ + TYPE=BS_DRIVER \ + EDKIIModule=DXEDRIVER\ + COMPRESS=1 diff --git a/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl new file mode 100644 index 0000000..b485486 --- /dev/null +++ b/ReferenceCode/ME/ActiveManagement/Sol/Dxe/PciSerial.sdl @@ -0,0 +1,24 @@ +TOKEN + Name = "PciSerial_SUPPORT" + Value = "1" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Help = "Main switch to enable PciSerial support in Project" +End +MODULE + Help = "Includes PciSerial.mak to Project" + File = "PciSerial.mak" +End + +PATH + Name = "PciSerial_DIR" + Help = "iAMT PciSerial file source directory" +End + +ELINK + Name = "$(BUILD_DIR)\PciSerial.ffs" + Parent = "FV_MAIN" + InvokeOrder = AfterParent +End
\ No newline at end of file |