summaryrefslogtreecommitdiff
path: root/EdkUnixPkg
diff options
context:
space:
mode:
authorklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-05-30 07:22:41 +0000
committerklu2 <klu2@6f19259b-4bc3-4df7-8a09-765794883524>2007-05-30 07:22:41 +0000
commitb19cfa69e7c2da5bb1a976ef0ca5c9d21a287695 (patch)
treefc18932d4fa561da545efdf52d44c8d18c767209 /EdkUnixPkg
parentd756d2e73917d24208200d342c4705d6dcfae09d (diff)
downloadedk2-platforms-b19cfa69e7c2da5bb1a976ef0ca5c9d21a287695.tar.xz
Add emulated serialIo device driver for EdkUnixPkg
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2605 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkUnixPkg')
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/ComponentName.c208
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.c1507
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.h507
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.msa87
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c10
-rw-r--r--EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa52
-rw-r--r--EdkUnixPkg/EdkUnixPkg.spd81
-rw-r--r--EdkUnixPkg/Include/Protocol/UnixIo.h10
-rw-r--r--EdkUnixPkg/Include/Protocol/UnixThunk.h59
-rw-r--r--EdkUnixPkg/Sec/UnixThunk.c15
-rw-r--r--EdkUnixPkg/Unix.fpd147
11 files changed, 2606 insertions, 77 deletions
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/ComponentName.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/ComponentName.c
new file mode 100644
index 0000000000..2b7cb92c64
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/ComponentName.c
@@ -0,0 +1,208 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "UnixSerialIo.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+UnixSerialIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoComponentNameGetControllerName (
+ 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 gUnixSerialIoComponentName = {
+ UnixSerialIoComponentNameGetDriverName,
+ UnixSerialIoComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mUnixSerialIoDriverNameTable[] = {
+ { "eng", L"Unix Serial I/O Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ 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.
+ 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.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gUnixSerialIoComponentName.SupportedLanguages,
+ mUnixSerialIoDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ 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.
+ 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.
+ 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.
+ 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.
+
+ Returns:
+ 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.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gUnixSerialIoDriverBinding.DriverBindingHandle,
+ &gEfiUnixIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // This is a bus driver, so ChildHandle must not be NULL.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEfiUnixIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiSerialIoProtocolGuid,
+ (VOID**)&SerialIo,
+ gUnixSerialIoDriverBinding.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);
+
+ return LookupUnicodeString (
+ Language,
+ gUnixSerialIoComponentName.SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.c
new file mode 100644
index 0000000000..58cc68961e
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.c
@@ -0,0 +1,1507 @@
+/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UnixSerialIo.c
+
+Abstract:
+
+ Our DriverBinding member functions operate on the handles
+ created by the NT Bus driver.
+
+ Handle(1) - UnixIo - DevicePath(1)
+
+ If a serial port is added to the system this driver creates a new handle.
+ The new handle is required, since the serial device must add an UART device
+ pathnode.
+
+ Handle(2) - SerialIo - DevicePath(1)\UART
+
+ The driver then adds a gEfiUnixSerialPortGuid as a protocol to Handle(1).
+ The instance data for this protocol is the private data used to create
+ Handle(2).
+
+ Handle(1) - UnixIo - DevicePath(1) - UnixSerialPort
+
+ If the driver is unloaded Handle(2) is removed from the system and
+ gEfiUnixSerialPortGuid is removed from Handle(1).
+
+ Note: Handle(1) is any handle created by the Win NT Bus driver that is passed
+ into the DriverBinding member functions of this driver. This driver requires
+ a Handle(1) to contain a UnixIo protocol, a DevicePath protocol, and
+ the TypeGuid in the UnixIo must be gEfiUnixSerialPortGuid.
+
+ If Handle(1) contains a gEfiUnixSerialPortGuid protocol then the driver is
+ loaded on the device.
+
+--*/
+
+#include "UnixSerialIo.h"
+#include <termio.h>
+
+EFI_DRIVER_BINDING_PROTOCOL gUnixSerialIoDriverBinding = {
+ UnixSerialIoDriverBindingSupported,
+ UnixSerialIoDriverBindingStart,
+ UnixSerialIoDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+STATIC
+VOID
+PrintSerialParameter(
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private
+ )
+{
+ struct termios Options;
+
+ if (Private->UnixThunk->Tcgetattr (Private->UnixHandle, &Options) == 0) {
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Input mode: 0x%x\r\n", Private->UnixHandle, Options.c_iflag));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Output mode: 0x%x\r\n", Private->UnixHandle, Options.c_oflag));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Control flag: 0x%x\r\n", Private->UnixHandle, Options.c_cflag));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Local mode flag: 0x%x\r\n", Private->UnixHandle, Options.c_lflag));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Line discipline: 0x%x\r\n", Private->UnixHandle, Options.c_line));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Input Speed: 0x%x\r\n", Private->UnixHandle, Options.c_ispeed));
+ DEBUG ((EFI_D_INFO, "Serial[0x%x]:Output Speed: 0x%x\r\n", Private->UnixHandle, Options.c_ospeed));
+ }
+}
+
+STATIC
+UINTN
+ConvertBaud2Unix (
+ UINT64 BaudRate
+ )
+{
+ switch (BaudRate) {
+ case 0:
+ return B0;
+ case 50:
+ return B50;
+ case 75:
+ return B75;
+ case 110:
+ return B110;
+ case 134:
+ return B134;
+ case 150:
+ return B150;
+ case 200:
+ return B200;
+ case 300:
+ return B300;
+ case 600:
+ return B600;
+ case 1200:
+ return B1200;
+ case 1800:
+ return B1800;
+ case 2400:
+ return B2400;
+ case 4800:
+ return B4800;
+ case 9600:
+ return B9600;
+ case 19200:
+ return B19200;
+ case 38400:
+ return B38400;
+ case 57600:
+ return B57600;
+ case 115200:
+ return B115200;
+ case 230400:
+ return B230400;
+ case 460800:
+ return B460800;
+ case 500000:
+ return B500000;
+ case 576000:
+ return B576000;
+ case 921600:
+ return B921600;
+ case 1000000:
+ return B1000000;
+ case 1152000:
+ return B1152000;
+ case 1500000:
+ return B1500000;
+ case 2000000:
+ return B2000000;
+ case 2500000:
+ return B2500000;
+ case 3000000:
+ return B3000000;
+ case 3500000:
+ return B3500000;
+ case 4000000:
+ return B4000000;
+ case __MAX_BAUD:
+ default:
+ DEBUG ((EFI_D_ERROR, "Invalid Baud Rate Parameter!\r\n"));
+ }
+ return -1;
+}
+
+STATIC
+UINTN
+ConvertByteSize2Unix (
+ UINT8 DataBit
+ )
+{
+ switch (DataBit) {
+ case 5:
+ return CS5;
+ case 6:
+ return CS6;
+ case 7:
+ return CS7;
+ case 8:
+ return CS8;
+ default:
+ DEBUG ((EFI_D_ERROR, "Invalid Data Size Parameter!\r\n"));
+ }
+ return -1;
+}
+
+STATIC
+VOID
+ConvertParity2Unix (
+ struct termios *Options,
+ EFI_PARITY_TYPE Parity
+ )
+{
+ switch (Parity) {
+ case NoParity:
+ Options->c_cflag &= ~PARENB;
+ break;
+ case EvenParity:
+ Options->c_cflag |= PARENB;
+ break;
+ case OddParity:
+ Options->c_cflag |= PARENB;
+ Options->c_cflag |= PARODD;
+ break;
+ case MarkParity:
+ Options->c_cflag = PARENB | CMSPAR | PARODD;
+ break;
+ case SpaceParity:
+ Options->c_cflag |= PARENB | CMSPAR;
+ Options->c_cflag &= ~PARODD;
+ break;
+ default:
+ DEBUG ((EFI_D_ERROR, "Invalid Parity Parameter!\r\n"));
+ }
+}
+
+STATIC
+VOID
+ConvertStopBit2Unix (
+ struct termios *Options,
+ EFI_STOP_BITS_TYPE StopBits
+ )
+{
+ switch (StopBits) {
+ case TwoStopBits:
+ Options->c_cflag |= CSTOPB;
+ break;
+ case OneStopBit:
+ case OneFiveStopBits:
+ case DefaultStopBits:
+ Options->c_cflag &= ~CSTOPB;
+ }
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+ The implementation of EFI_DRIVER_BINDING_PROTOCOL.EFI_DRIVER_BINDING_SUPPORTED.
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UART_DEVICE_PATH *UartNode;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ParentDevicePath,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID**)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure that the Unix Thunk Protocol is valid
+ //
+ if (UnixIo->UnixThunk->Signature != EFI_UNIX_THUNK_PROTOCOL_SIGNATURE) {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+ }
+
+ //
+ // Check the GUID to see if this is a handle type the driver supports
+ //
+ if (!CompareGuid (UnixIo->TypeGuid, &gEfiUnixSerialPortGuid)) {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+ }
+
+ if (RemainingDevicePath != NULL) {
+ Status = EFI_UNSUPPORTED;
+ UartNode = (UART_DEVICE_PATH *) RemainingDevicePath;
+ 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 < 0 || 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 (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ UINTN UnixHandle;
+ UART_DEVICE_PATH Node;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+ UINTN EntryCount;
+ UINTN Index;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ CHAR8 AsciiDevName[1024];
+
+ DEBUG ((EFI_D_INFO, "SerialIo drive binding start!\r\n"));
+ Private = NULL;
+ UnixHandle = -1;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ParentDevicePath,
+ This->DriverBindingHandle,
+ Handle,
+ 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 (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID**)&UnixIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ gBS->CloseProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ return Status;
+ }
+
+ 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 (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ &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,
+ Handle,
+ 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;
+ }
+
+ //
+ // Check to see if we can access the hardware device. If it's Open in Unix we
+ // will not get access.
+ //
+ UnicodeStrToAsciiStr(UnixIo->EnvString, AsciiDevName);
+ UnixHandle = UnixIo->UnixThunk->Open (AsciiDevName, O_RDWR | O_NOCTTY, 0);
+
+ if (UnixHandle == -1) {
+ DEBUG ((EFI_D_INFO, "Faile to open serial device, %s!\r\n", UnixIo->EnvString ));
+ UnixIo->UnixThunk->Perror (AsciiDevName);
+ Status = EFI_DEVICE_ERROR;
+ goto Error;
+ }
+ DEBUG ((EFI_D_INFO, "Success to open serial device %s, Hanle = 0x%x \r\n", UnixIo->EnvString, UnixHandle));
+
+ //
+ // Construct Private data
+ //
+ Private = AllocatePool (sizeof (UNIX_SERIAL_IO_PRIVATE_DATA));
+ if (Private == NULL) {
+ goto Error;
+ }
+
+ //
+ // This signature must be valid before any member function is called
+ //
+ Private->Signature = UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE;
+ Private->UnixHandle = UnixHandle;
+ Private->ControllerHandle = Handle;
+ Private->Handle = NULL;
+ Private->UnixThunk = UnixIo->UnixThunk;
+ Private->ParentDevicePath = ParentDevicePath;
+ Private->ControllerNameTable = NULL;
+
+ Private->SoftwareLoopbackEnable = FALSE;
+ Private->HardwareLoopbackEnable = FALSE;
+ Private->HardwareFlowControl = FALSE;
+ Private->Fifo.First = 0;
+ Private->Fifo.Last = 0;
+ Private->Fifo.Surplus = SERIAL_MAX_BUFFER_SIZE;
+
+ AddUnicodeString (
+ "eng",
+ gUnixSerialIoComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ UnixIo->EnvString
+ );
+
+ Private->SerialIo.Revision = SERIAL_IO_INTERFACE_REVISION;
+ Private->SerialIo.Reset = UnixSerialIoReset;
+ Private->SerialIo.SetAttributes = UnixSerialIoSetAttributes;
+ Private->SerialIo.SetControl = UnixSerialIoSetControl;
+ Private->SerialIo.GetControl = UnixSerialIoGetControl;
+ Private->SerialIo.Write = UnixSerialIoWrite;
+ Private->SerialIo.Read = UnixSerialIoRead;
+ Private->SerialIo.Mode = &Private->SerialIoMode;
+
+ if (RemainingDevicePath != NULL) {
+ //
+ // Match the configuration of the RemainingDevicePath. IsHandleSupported()
+ // already checked to make sure the RemainingDevicePath contains settings
+ // that we can support.
+ //
+ CopyMem (&Private->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));
+ } else {
+ //
+ // Build the device path by appending the UART node to the ParentDevicePath
+ // from the UnixIo handle. The Uart setings are zero here, since
+ // SetAttribute() will update them to match the default setings.
+ //
+ ZeroMem (&Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
+ Private->UartDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ Private->UartDevicePath.Header.SubType = MSG_UART_DP;
+ SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));
+ }
+
+ //
+ // Build the device path by appending the UART node to the ParentDevicePath
+ // from the UnixIo handle. The Uart setings are zero here, since
+ // SetAttribute() will update them to match the current setings.
+ //
+ Private->DevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
+ );
+ if (Private->DevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
+ //
+ Private->SerialIoMode.ControlMask = SERIAL_CONTROL_MASK;
+ Private->SerialIoMode.Timeout = SERIAL_TIMEOUT_DEFAULT;
+ Private->SerialIoMode.BaudRate = Private->UartDevicePath.BaudRate;
+ Private->SerialIoMode.ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;
+ Private->SerialIoMode.DataBits = Private->UartDevicePath.DataBits;
+ Private->SerialIoMode.Parity = Private->UartDevicePath.Parity;
+ Private->SerialIoMode.StopBits = Private->UartDevicePath.StopBits;
+
+ //
+ // Issue a reset to initialize the COM port
+ //
+ Status = Private->SerialIo.Reset (&Private->SerialIo);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ //
+ // Create new child handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiSerialIoProtocolGuid,
+ &Private->SerialIo,
+ &gEfiDevicePathProtocolGuid,
+ Private->DevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ //
+ // Open For Child Device
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID**)&UnixIo,
+ This->DriverBindingHandle,
+ Private->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ return EFI_SUCCESS;
+
+Error:
+ //
+ // Use the Stop() function to free all resources allocated in Start()
+ //
+ if (Private != NULL) {
+ if (Private->Handle != NULL) {
+ This->Stop (This, Handle, 1, &Private->Handle);
+ } else {
+ if (UnixHandle != -1) {
+ Private->UnixThunk->Close (UnixHandle);
+ }
+
+ if (Private->DevicePath != NULL) {
+ FreePool (Private->DevicePath);
+ }
+
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ FreePool (Private);
+ }
+ }
+
+ This->Stop (This, Handle, 0, NULL);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ EFI_UNIX_IO_PROTOCOL *UnixIo;
+
+ //
+ // 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 (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ Status = gBS->CloseProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ return Status;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEfiSerialIoProtocolGuid,
+ (VOID**)&SerialIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);
+
+ ASSERT (Private->Handle == ChildHandleBuffer[Index]);
+
+ Status = gBS->CloseProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiSerialIoProtocolGuid,
+ &Private->SerialIo,
+ &gEfiDevicePathProtocolGuid,
+ Private->DevicePath,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ Handle,
+ &gEfiUnixIoProtocolGuid,
+ (VOID **) &UnixIo,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ Private->UnixThunk->Close (Private->UnixHandle);
+
+ FreePool (Private->DevicePath);
+
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ FreePool (Private);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// Serial IO Protocol member functions
+//
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+{
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ EFI_TPL Tpl;
+ UINTN UnixStatus;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ UnixStatus = Private->UnixThunk->Tcflush (
+ Private->UnixHandle,
+ TCIOFLUSH
+ );
+ switch (UnixStatus) {
+ case EBADF:
+ DEBUG ((EFI_D_ERROR, "Invalid handle of serial device!\r\n"));
+ return EFI_DEVICE_ERROR;
+ case EINVAL:
+ DEBUG ((EFI_D_ERROR, "Invalid queue selector!\r\n"));
+ return EFI_DEVICE_ERROR;
+ case ENOTTY:
+ DEBUG ((EFI_D_ERROR, "The file associated with serial's handle is not a terminal!\r\n"));
+ return EFI_DEVICE_ERROR;
+ default:
+ DEBUG ((EFI_D_ERROR, "The serial IO device is reset successfully!\r\n"));
+ }
+
+ gBS->RestoreTPL (Tpl);
+
+ return This->SetAttributes (
+ This,
+ This->Mode->BaudRate,
+ This->Mode->ReceiveFifoDepth,
+ This->Mode->Timeout,
+ This->Mode->Parity,
+ (UINT8) This->Mode->DataBits,
+ This->Mode->StopBits
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoSetAttributes (
+ 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
+ )
+/*++
+
+Routine Description:
+
+ This function is used to set the attributes.
+
+Arguments:
+
+ This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
+ BaudRate - The Baud rate of the serial device.
+ ReceiveFifoDepth - The request depth of fifo on receive side.
+ Timeout - the request timeout for a single charact.
+ Parity - The type of parity used in serial device.
+ DataBits - Number of deata bits used in serial device.
+ StopBits - Number of stop bits used in serial device.
+
+Returns:
+ Status code
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ EFI_TPL Tpl;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ //
+ // Some of our arguments have defaults if a null value is passed in, and
+ // we must set the default values if a null argument is passed in.
+ //
+ if (BaudRate == 0) {
+ BaudRate = SERIAL_BAUD_DEFAULT;
+ }
+
+ if (ReceiveFifoDepth == 0) {
+ ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;
+ }
+
+ if (Timeout == 0) {
+ Timeout = SERIAL_TIMEOUT_DEFAULT;
+ }
+
+ if (Parity == DefaultParity) {
+ Parity = NoParity;
+ }
+
+ if (DataBits == 0) {
+ DataBits = SERIAL_DATABITS_DEFAULT;
+ }
+
+ if (StopBits == DefaultStopBits) {
+ StopBits = OneStopBit;
+ }
+
+ //
+ // See if the new attributes already match the current attributes
+ //
+ if (Private->UartDevicePath.BaudRate == BaudRate &&
+ Private->UartDevicePath.DataBits == DataBits &&
+ Private->UartDevicePath.Parity == Parity &&
+ Private->UartDevicePath.StopBits == StopBits &&
+ Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth &&
+ Private->SerialIoMode.Timeout == Timeout ) {
+ gBS->RestoreTPL(Tpl);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Try to get options from serial device.
+ //
+ if (Private->UnixThunk->Tcgetattr (Private->UnixHandle, &Private->UnixTermios) == -1) {
+ Private->UnixThunk->Perror ("IoSetAttributes");
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Setting Baud Rate
+ //
+ Private->UnixThunk->Cfsetispeed (&Private->UnixTermios, ConvertBaud2Unix(BaudRate));
+ Private->UnixThunk->Cfsetospeed (&Private->UnixTermios, ConvertBaud2Unix(BaudRate));
+ //
+ // Setting DataBits
+ //
+ Private->UnixTermios.c_cflag &= ~CSIZE;
+ Private->UnixTermios.c_cflag |= ConvertByteSize2Unix (DataBits);
+ //
+ // Setting Parity
+ //
+ ConvertParity2Unix (&Private->UnixTermios, Parity);
+ //
+ // Setting StopBits
+ //
+ ConvertStopBit2Unix (&Private->UnixTermios, StopBits);
+ //
+ // Raw input
+ //
+ Private->UnixTermios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+ //
+ // Raw output
+ //
+ Private->UnixTermios.c_oflag &= ~OPOST;
+ //
+ // Support hardware flow control
+ //
+ Private->UnixTermios.c_cflag &= ~CRTSCTS;;
+ //
+ // Time out
+ //
+ Private->UnixTermios.c_cc[VMIN] = 0;
+ Private->UnixTermios.c_cc[VTIME] = (Timeout/1000000) * 10;
+
+ //
+ // Set the options
+ //
+ if (-1 == Private->UnixThunk->Tcsetattr (
+ Private->UnixHandle,
+ TCSANOW,
+ &Private->UnixTermios
+ )) {
+ DEBUG ((EFI_D_INFO, "Fail to set options for serial device!\r\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Update mode
+ //
+ Private->SerialIoMode.BaudRate = BaudRate;
+ Private->SerialIoMode.ReceiveFifoDepth = ReceiveFifoDepth;
+ Private->SerialIoMode.Timeout = Timeout;
+ Private->SerialIoMode.Parity = Parity;
+ Private->SerialIoMode.DataBits = DataBits;
+ Private->SerialIoMode.StopBits = StopBits;
+ //
+ // See if Device Path Node has actually changed
+ //
+ if (Private->UartDevicePath.BaudRate == BaudRate &&
+ Private->UartDevicePath.DataBits == DataBits &&
+ Private->UartDevicePath.Parity == Parity &&
+ Private->UartDevicePath.StopBits == StopBits ) {
+ gBS->RestoreTPL(Tpl);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Update the device path
+ //
+ Private->UartDevicePath.BaudRate = BaudRate;
+ Private->UartDevicePath.DataBits = DataBits;
+ Private->UartDevicePath.Parity = (UINT8) Parity;
+ Private->UartDevicePath.StopBits = (UINT8) StopBits;
+
+ NewDevicePath = AppendDevicePathNode (
+ Private->ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath
+ );
+ if (NewDevicePath == NULL) {
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Private->Handle != NULL) {
+ Status = gBS->ReinstallProtocolInterface (
+ Private->Handle,
+ &gEfiDevicePathProtocolGuid,
+ Private->DevicePath,
+ NewDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->RestoreTPL (Tpl);
+ return Status;
+ }
+ }
+
+ if (Private->DevicePath != NULL) {
+ FreePool (Private->DevicePath);
+ }
+
+ Private->DevicePath = NewDevicePath;
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoSetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Control - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ UINTN Result;
+ UINTN Status;
+ struct termios Options;
+ EFI_TPL Tpl;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &Status);
+
+ if (Result == -1) {
+ Private->UnixThunk->Perror ("SerialSetControl");
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Private->HardwareFlowControl = FALSE;
+ Private->SoftwareLoopbackEnable = FALSE;
+ Private->HardwareLoopbackEnable = FALSE;
+
+ if (Control & EFI_SERIAL_REQUEST_TO_SEND) {
+ Options.c_cflag |= TIOCM_RTS;
+ }
+
+ if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {
+ Options.c_cflag |= TIOCM_DTR;
+ }
+
+ if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {
+ Private->HardwareFlowControl = TRUE;
+ }
+
+ if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {
+ Private->SoftwareLoopbackEnable = TRUE;
+ }
+
+ if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) {
+ Private->HardwareLoopbackEnable = TRUE;
+ }
+
+ Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMSET, &Status);
+
+ if (Result == -1) {
+ Private->UnixThunk->Perror ("SerialSetControl");
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoGetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Control - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ UINTN Result;
+ UINTN Status;
+ struct termios Options;
+ UINT32 Bits;
+ EFI_TPL Tpl;
+ UINTN Bytes;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+ Result = Private->UnixThunk->IoCtl (Private->UnixHandle, TIOCMGET, &Status);
+ if (Result == -1) {
+ Private->UnixThunk->Perror ("SerialGetControl");
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((Status & TIOCM_CTS) == TIOCM_CTS) {
+ Bits |= EFI_SERIAL_CLEAR_TO_SEND;
+ }
+
+ if ((Status & TIOCM_DSR) == TIOCM_DSR) {
+ Bits |= EFI_SERIAL_DATA_SET_READY;
+ }
+
+ if ((Status & TIOCM_DTR) == TIOCM_DTR) {
+ Bits |= EFI_SERIAL_DATA_TERMINAL_READY;
+ }
+
+ if ((Status & TIOCM_RTS) == TIOCM_RTS) {
+ Bits |= EFI_SERIAL_REQUEST_TO_SEND;
+ }
+
+ if ((Status & TIOCM_RNG) == TIOCM_RNG) {
+ Bits |= EFI_SERIAL_RING_INDICATE;
+ }
+
+ if ((Status & TIOCM_CAR) == TIOCM_CAR) {
+ Bits |= EFI_SERIAL_CARRIER_DETECT;
+ }
+
+ if (Private->HardwareFlowControl) {
+ Bits |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ }
+
+ if (Private->SoftwareLoopbackEnable) {
+ Bits |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
+ }
+
+ if (Private->HardwareLoopbackEnable) {
+ Bits |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;
+ }
+
+ Result = Private->UnixThunk->IoCtl (Private->UnixHandle, FIONREAD, &Bytes);
+ if (Result == -1) {
+ Private->UnixThunk->Perror ("SerialGetControl");
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Bytes == 0) {
+ Bits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ }
+
+ *Control = Bits;
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoWrite (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ UINT8 *ByteBuffer;
+ UINT32 TotalBytesWritten;
+ UINT32 BytesToGo;
+ UINT32 BytesWritten;
+ UINT32 Index;
+ UINT32 Control;
+ EFI_TPL Tpl;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ ByteBuffer = (UINT8 *) Buffer;
+ TotalBytesWritten = 0;
+
+ if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {
+ for (Index = 0; Index < *BufferSize; Index++) {
+ if (IsaSerialFifoAdd (&Private->Fifo, ByteBuffer[Index]) == EFI_SUCCESS) {
+ TotalBytesWritten++;
+ } else {
+ break;
+ }
+ }
+ } else {
+ BytesToGo = (*BufferSize);
+
+ do {
+ if (Private->HardwareFlowControl) {
+ //
+ // Send RTS
+ //
+ UnixSerialIoGetControl (&Private->SerialIo, &Control);
+ Control |= EFI_SERIAL_REQUEST_TO_SEND;
+ UnixSerialIoSetControl (&Private->SerialIo, Control);
+ }
+
+ //
+ // Do the write
+ //
+ BytesWritten = Private->UnixThunk->Write (
+ Private->UnixHandle,
+ &ByteBuffer[TotalBytesWritten],
+ BytesToGo
+ );
+
+ if (Private->HardwareFlowControl) {
+ //
+ // Assert RTS
+ //
+ UnixSerialIoGetControl (&Private->SerialIo, &Control);
+ Control &= ~ (UINT32) EFI_SERIAL_REQUEST_TO_SEND;
+ UnixSerialIoSetControl (&Private->SerialIo, Control);
+ }
+
+ TotalBytesWritten += BytesWritten;
+ BytesToGo -= BytesWritten;
+ } while (BytesToGo > 0);
+ }
+
+ *BufferSize = TotalBytesWritten;
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoRead (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ EFI_DEVICE_ERROR - TODO: Add description for return value
+
+--*/
+{
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private;
+ UINT32 BytesRead;
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINT8 Data;
+ UINT32 Control;
+ EFI_TPL Tpl;
+
+ Tpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Private = UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ //
+ // Do the read
+ //
+ if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {
+ for (Index = 0, BytesRead = 0; Index < *BufferSize; Index++) {
+ if (IsaSerialFifoRemove (&Private->Fifo, &Data) == EFI_SUCCESS) {
+ ((UINT8 *) Buffer)[Index] = Data;
+ BytesRead++;
+ } else {
+ break;
+ }
+ }
+ } else {
+ if (Private->HardwareFlowControl) {
+ UnixSerialIoGetControl (&Private->SerialIo, &Control);
+ Control |= EFI_SERIAL_DATA_TERMINAL_READY;
+ UnixSerialIoSetControl (&Private->SerialIo, Control);
+ }
+
+ BytesRead = Private->UnixThunk->Read (Private->UnixHandle, Buffer, *BufferSize);
+ if (Private->HardwareFlowControl) {
+ UnixSerialIoGetControl (&Private->SerialIo, &Control);
+ Control &= ~ (UINT32) EFI_SERIAL_DATA_TERMINAL_READY;
+ UnixSerialIoSetControl (&Private->SerialIo, Control);
+ }
+
+ }
+
+ if (BytesRead != *BufferSize) {
+ Status = EFI_TIMEOUT;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ *BufferSize = (UINTN) BytesRead;
+
+ gBS->RestoreTPL (Tpl);
+
+ return Status;
+}
+
+BOOLEAN
+IsaSerialFifoFull (
+ IN SERIAL_DEV_FIFO *Fifo
+ )
+/*++
+
+ Routine Description:
+ Detect whether specific FIFO is full or not
+
+ Arguments:
+ Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
+
+ Returns:
+ TRUE: the FIFO is full
+ FALSE: the FIFO is not full
+
+--*/
+{
+ if (Fifo->Surplus == 0) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+BOOLEAN
+IsaSerialFifoEmpty (
+ IN SERIAL_DEV_FIFO *Fifo
+ )
+/*++
+
+ Routine Description:
+ Detect whether specific FIFO is empty or not
+
+ Arguments:
+ Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
+
+ Returns:
+ TRUE: the FIFO is empty
+ FALSE: the FIFO is not empty
+
+--*/
+{
+ if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+EFI_STATUS
+IsaSerialFifoAdd (
+ IN SERIAL_DEV_FIFO *Fifo,
+ IN UINT8 Data
+ )
+/*++
+
+ Routine Description:
+ Add data to specific FIFO
+
+ Arguments:
+ Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
+ Data UINT8: the data added to FIFO
+
+ Returns:
+ EFI_SUCCESS: Add data to specific FIFO successfully
+ EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
+
+--*/
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+{
+ //
+ // if FIFO full can not add data
+ //
+ if (IsaSerialFifoFull (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;
+}
+
+EFI_STATUS
+IsaSerialFifoRemove (
+ IN SERIAL_DEV_FIFO *Fifo,
+ OUT UINT8 *Data
+ )
+/*++
+
+ Routine Description:
+ Remove data from specific FIFO
+
+ Arguments:
+ Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
+ Data UINT8*: the data removed from FIFO
+
+ Returns:
+ EFI_SUCCESS: Remove data from specific FIFO successfully
+ EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
+
+--*/
+// TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+{
+ //
+ // if FIFO is empty, no data can remove
+ //
+ if (IsaSerialFifoEmpty (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;
+}
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.h b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.h
new file mode 100644
index 0000000000..30109e2529
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.h
@@ -0,0 +1,507 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ UnixSerialIo.h
+
+Abstract:
+
+
+--*/
+
+#ifndef _UNIXPKG_SERIAL_IO_
+#define _UNIXPKG_SERIAL_IO_
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define SERIAL_MAX_BUFFER_SIZE 256
+#define TIMEOUT_STALL_INTERVAL 10
+
+typedef struct {
+ UINT32 First;
+ UINT32 Last;
+ UINT32 Surplus;
+ UINT8 Data[SERIAL_MAX_BUFFER_SIZE];
+} SERIAL_DEV_FIFO;
+
+#define UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('U', 'N', 's', 'i')
+typedef struct {
+ UINT64 Signature;
+
+ //
+ // Protocol data for the new handle we are going to add
+ //
+ EFI_HANDLE Handle;
+ EFI_SERIAL_IO_PROTOCOL SerialIo;
+ EFI_SERIAL_IO_MODE SerialIoMode;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Private Data
+ //
+ EFI_HANDLE ControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ UART_DEVICE_PATH UartDevicePath;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+ //
+ // Private NT type Data;
+ //
+ UINTN UnixHandle;
+ struct termios UnixTermios;
+
+ BOOLEAN SoftwareLoopbackEnable;
+ BOOLEAN HardwareFlowControl;
+ BOOLEAN HardwareLoopbackEnable;
+
+ SERIAL_DEV_FIFO Fifo;
+
+} UNIX_SERIAL_IO_PRIVATE_DATA;
+
+#define UNIX_SERIAL_IO_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, UNIX_SERIAL_IO_PRIVATE_DATA, SerialIo, UNIX_SERIAL_IO_PRIVATE_DATA_SIGNATURE)
+
+//
+// Global Protocol Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUnixSerialIoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUnixSerialIoComponentName;
+
+//
+// Macros to convert EFI serial types to NT serial types.
+//
+
+//
+// one second
+//
+#define SERIAL_TIMEOUT_DEFAULT (1000 * 1000)
+#define SERIAL_BAUD_DEFAULT 115200
+#define SERIAL_FIFO_DEFAULT 14
+#define SERIAL_DATABITS_DEFAULT 8
+#define SERIAL_PARITY_DEFAULT DefaultParity
+#define SERIAL_STOPBITS_DEFAULT DefaultStopBits
+
+#define SERIAL_CONTROL_MASK (EFI_SERIAL_CLEAR_TO_SEND | \
+ EFI_SERIAL_DATA_SET_READY | \
+ EFI_SERIAL_RING_INDICATE | \
+ EFI_SERIAL_CARRIER_DETECT | \
+ EFI_SERIAL_REQUEST_TO_SEND | \
+ EFI_SERIAL_DATA_TERMINAL_READY | \
+ EFI_SERIAL_INPUT_BUFFER_EMPTY)
+
+#define ConvertBaud2Nt(x) (DWORD) x
+#define ConvertData2Nt(x) (BYTE) x
+
+#define ConvertParity2Nt(x) \
+ (BYTE) ( \
+ x == DefaultParity ? NOPARITY : \
+ x == NoParity ? NOPARITY : \
+ x == EvenParity ? EVENPARITY : \
+ x == OddParity ? ODDPARITY : \
+ x == MarkParity ? MARKPARITY : \
+ x == SpaceParity ? SPACEPARITY : 0 \
+ )
+
+#define ConvertStop2Nt(x) \
+ (BYTE) ( \
+ x == DefaultParity ? ONESTOPBIT : \
+ x == OneFiveStopBits ? ONE5STOPBITS : \
+ x == TwoStopBits ? TWOSTOPBITS : 0 \
+ )
+
+#define ConvertTime2Nt(x) ((x) / 1000)
+
+//
+// 115400 baud with rounding errors
+//
+#define SERIAL_PORT_MAX_BAUD_RATE 115400
+
+//
+// Function Prototypes
+//
+EFI_STATUS
+EFIAPI
+InitializeUnixSerialIo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+ SystemTable - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ RemainingDevicePath - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Handle - TODO: add argument description
+ NumberOfChildren - TODO: add argument description
+ ChildHandleBuffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoSetAttributes (
+ 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
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BaudRate - TODO: add argument description
+ ReceiveFifoDepth - TODO: add argument description
+ Timeout - TODO: add argument description
+ Parity - TODO: add argument description
+ DataBits - TODO: add argument description
+ StopBits - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoSetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Control - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoGetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ Control - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoWrite (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UnixSerialIoRead (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ This - TODO: add argument description
+ BufferSize - TODO: add argument description
+ Buffer - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsaSerialFifoFull (
+ IN SERIAL_DEV_FIFO *Fifo
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Fifo - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+BOOLEAN
+IsaSerialFifoEmpty (
+ IN SERIAL_DEV_FIFO *Fifo
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Fifo - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+IsaSerialFifoAdd (
+ IN SERIAL_DEV_FIFO *Fifo,
+ IN UINT8 Data
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Fifo - TODO: add argument description
+ Data - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+IsaSerialFifoRemove (
+ IN SERIAL_DEV_FIFO *Fifo,
+ OUT UINT8 *Data
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Fifo - TODO: add argument description
+ Data - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+IsaSerialReceiveTransmit (
+ UNIX_SERIAL_IO_PRIVATE_DATA *Private
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ Private - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.msa
new file mode 100644
index 0000000000..793d24a3f3
--- /dev/null
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.msa
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>UnixSerialIo</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>600F2BF2-63A7-48ca-9FD0-A3450B87EE05</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Serial I/O driver</Abstract>
+ <Description>Our DriverBinding member functions operate on the handles
+ created by the Unix Bus driver</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UnixSerialIo</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>UnixSerialIo.h</Filename>
+ <Filename>UnixSerialIo.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiUnixIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSerialIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixSerialPortGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gUnixSerialIoDriverBinding</DriverBinding>
+ <ComponentName>gUnixSerialIoComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea> \ No newline at end of file
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c
index efa66abeeb..b8611f66d2 100644
--- a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.c
@@ -122,6 +122,7 @@ static UNIX_PCD_ENTRY mPcdEnvironment[] = {
{PcdToken(PcdUnixConsole), &gEfiUnixConsoleGuid},
{PcdToken(PcdUnixUga), &gEfiUnixUgaGuid},
{PcdToken(PcdUnixFileSystem), &gEfiUnixFileSystemGuid},
+ {PcdToken(PcdUnixSerialPort), &gEfiUnixSerialPortGuid},
{PcdToken(PcdUnixVirtualDisk), &gEfiUnixVirtualDisksGuid},
{PcdToken(PcdUnixPhysicalDisk), &gEfiUnixPhysicalDisksGuid},
{PcdToken(PcdUnixCpuModel), &gEfiUnixCPUModelGuid},
@@ -293,10 +294,10 @@ Returns:
{
EFI_STATUS Status;
EFI_STATUS InstallStatus;
- EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
+ EFI_UNIX_THUNK_PROTOCOL *UnixThunk;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- UNIX_BUS_DEVICE *UnixBusDevice;
- UNIX_IO_DEVICE *UnixDevice;
+ UNIX_BUS_DEVICE *UnixBusDevice;
+ UNIX_IO_DEVICE *UnixDevice;
UINTN Index;
CHAR16 *StartString;
CHAR16 *SubString;
@@ -428,7 +429,6 @@ Returns:
}
if (CreateDevice) {
-
//
// Allocate instance structure, and fill in parent information.
//
@@ -441,7 +441,7 @@ Returns:
UnixDevice->ControllerHandle = ControllerHandle;
UnixDevice->ParentDevicePath = ParentDevicePath;
- UnixDevice->UnixIo.UnixThunk = UnixThunk;
+ UnixDevice->UnixIo.UnixThunk = UnixThunk;
//
// Plus 2 to account for the NULL at the end of the Unicode string
diff --git a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa
index b64a8216de..6422c062f5 100644
--- a/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa
+++ b/EdkUnixPkg/Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa
@@ -1,22 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
-<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MsaHeader>
<ModuleName>UnixBusDriver</ModuleName>
<ModuleType>UEFI_DRIVER</ModuleType>
<GuidValue>f320d656-8985-11db-90e0-0040d02b1835</GuidValue>
<Version>1.0</Version>
<Abstract>Unix Bus driver</Abstract>
- <Description>
- This following section documents the envirnoment variables for the Win NT
- build. These variables are used to define the (virtual) hardware
- configuration of the NT environment
- </Description>
+ <Description>This following section documents the envirnoment variables for the Win NT
+ build. These variables are used to define the (virtual) hardware
+ configuration of the NT environment</Description>
<Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
- <License>All rights reserved. This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
@@ -106,6 +104,9 @@
<GuidCNames Usage="ALWAYS_CONSUMED">
<GuidCName>gEfiUnixCPUSpeedGuid</GuidCName>
</GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiUnixSerialPortGuid</GuidCName>
+ </GuidCNames>
</Guids>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
@@ -119,41 +120,41 @@
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixConsole</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD declares the title string of the text console window.
- such as "My EFI Console".
+ <HelpText>This PCD declares the title string of the text console window.
+ such as "My EFI Console".
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixUga</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD declares the resolutions for the UGA windows.
+ <HelpText>This PCD declares the resolutions for the UGA windows.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixFileSystem</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD defines the unix directory who will be mounted as
- harddisk in simulator.
+ <HelpText>This PCD defines the unix directory who will be mounted as
+ harddisk in simulator.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixVirtualDisk</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD defines the devices which use a file to emulate a hard disk or
- removable media device
+ <HelpText>This PCD defines the devices which use a file to emulate a hard disk or
+ removable media device
The item type if this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixPhysicalDisk</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD defines physical disk which will be simualted as a
- harddisk in simulator.
+ <HelpText>This PCD defines physical disk which will be simualted as a
+ harddisk in simulator.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixCpuModel</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD defines simulated CPU model string.
+ <HelpText>This PCD defines simulated CPU model string.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry PcdItemType="DYNAMIC">
@@ -164,8 +165,13 @@
<PcdEntry PcdItemType="DYNAMIC">
<C_Name>PcdUnixMemorySize</C_Name>
<TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
- <HelpText>This PCD defines the size of simulated memory size.
+ <HelpText>This PCD defines the size of simulated memory size.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdUnixSerialPort</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>Simulation serial IO port</HelpText>
+ </PcdEntry>
</PcdCoded>
-</ModuleSurfaceArea>
+</ModuleSurfaceArea> \ No newline at end of file
diff --git a/EdkUnixPkg/EdkUnixPkg.spd b/EdkUnixPkg/EdkUnixPkg.spd
index c4360e89f2..a9622dd4bb 100644
--- a/EdkUnixPkg/EdkUnixPkg.spd
+++ b/EdkUnixPkg/EdkUnixPkg.spd
@@ -1,15 +1,5 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (c) 2006 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
--->
-<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+<?xml version="1.0" encoding="UTF-8"?>
+<PackageSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SpdHeader>
<PackageName>EdkUnixPkg</PackageName>
<GuidValue>f2805c44-8985-11db-9e98-0040d02b1835</GuidValue>
@@ -26,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</SpdHeader>
<PackageDefinitions>
- <ReadOnly>true</ReadOnly>
+ <ReadOnly>false</ReadOnly>
<RePackage>false</RePackage>
</PackageDefinitions>
<LibraryClassDeclarations>
@@ -92,6 +82,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<Filename>Dxe/UnixThunk/Bus/Console/UnixConsole.msa</Filename>
<Filename>Dxe/UnixThunk/Bus/SimpleFileSystem/UnixSimpleFileSystem.msa</Filename>
<Filename>Dxe/UnixThunk/Bus/Uga/UnixUga.msa</Filename>
+ <Filename>Dxe/UnixThunk/Bus/SerialIo/UnixSerialIo.msa</Filename>
<Filename>Dxe/UnixThunk/Bus/UnixBusDriver/UnixBusDriver.msa</Filename>
<Filename>Dxe/UnixThunk/Chipset/Metronome/Metronome.msa</Filename>
<Filename>Dxe/UnixThunk/Chipset/RealTimeClock/RealTimeClock.msa</Filename>
@@ -172,6 +163,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<GuidValue>f2de8f12-8985-11db-aabc-0040d02b1835</GuidValue>
<HelpText/>
</Entry>
+ <Entry Name="UnixSerialPort">
+ <C_Name>gEfiUnixSerialPortGuid</C_Name>
+ <GuidValue>6d3a727d-66c8-4d19-87e6-0215861490f3</GuidValue>
+ <HelpText/>
+ </Entry>
</GuidDeclarations>
<ProtocolDeclarations>
<Entry Name="UnixIo">
@@ -220,7 +216,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"E:RW;245760;512"</DefaultValue>
- <HelpText>This PCD defines physical disk which will be simualted as a
+ <HelpText>This PCD defines physical disk which will be simualted as a
harddisk in simulator. The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -230,7 +226,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"FW;40960;512"</DefaultValue>
- <HelpText>This PCD defines the devices which use a file to emulate a hard disk or
+ <HelpText>This PCD defines the devices which use a file to emulate a hard disk or
removable media device.The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -240,7 +236,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"UGA Window"</DefaultValue>
- <HelpText>This PCD declares the resolutions for the UGA windows.
+ <HelpText>This PCD declares the resolutions for the UGA windows.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -250,8 +246,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L".!..\\..\\..\\..\\..\\EdkShellBinPkg\\bin\\ia32\\Apps"</DefaultValue>
- <HelpText>This PCD defines the host directory who will be mounted as
- harddisk in simulator.
+ <HelpText>This PCD defines the host directory who will be mounted as
+ harddisk in simulator.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -261,8 +257,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"64!64"</DefaultValue>
- <HelpText>This PCD defines the memory size of simulated machine. Simulator will allocate
- the size of PcdUnixMemorySize in host platform.
+ <HelpText>This PCD defines the memory size of simulated machine. Simulator will allocate
+ the size of PcdUnixMemorySize in host platform.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -272,18 +268,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>UINT32</DatumType>
<ValidUsage>FIXED_AT_BUILD PATCHABLE_IN_MODULE</ValidUsage>
<DefaultValue>1</DefaultValue>
- <HelpText>This PCD defines the boot mode for simualtor.
- The boot mode can be set as following value:
- 0x0: Boot with full configuration.
- 0x1: Boot with minimal configuration.
- 0x2: Boot assume no configuration changes.
- 0x3: Boot with full configuration plus diagnostics.
- 0x4: Boot with default settings.
- 0x5: Boot on S4 resume.
- 0x6: Boot on S5 resume.
- 0x10: Boot on S2 resume.
- 0x11: Boot on S3 resume.
- 0x12: Boot on flash update.
+ <HelpText>This PCD defines the boot mode for simualtor.
+ The boot mode can be set as following value:
+ 0x0: Boot with full configuration.
+ 0x1: Boot with minimal configuration.
+ 0x2: Boot assume no configuration changes.
+ 0x3: Boot with full configuration plus diagnostics.
+ 0x4: Boot with default settings.
+ 0x5: Boot on S4 resume.
+ 0x6: Boot on S5 resume.
+ 0x10: Boot on S2 resume.
+ 0x11: Boot on S3 resume.
+ 0x12: Boot on flash update.
0x20: Boot in reovery mode.</HelpText>
</PcdEntry>
<PcdEntry>
@@ -293,7 +289,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"Intel(R) Processor Model"</DefaultValue>
- <HelpText>This PCD defines simulated CPU model string.
+ <HelpText>This PCD defines simulated CPU model string.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -303,7 +299,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"3000"</DefaultValue>
- <HelpText>This PCD defines simulated CPU speed string.
+ <HelpText>This PCD defines simulated CPU speed string.
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -322,8 +318,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>DYNAMIC</ValidUsage>
<DefaultValue>L"Bus Driver Console Window"</DefaultValue>
- <HelpText>This PCD declares the title string of the text console window.
- such as "My EFI Console".
+ <HelpText>This PCD declares the title string of the text console window.
+ such as "My EFI Console".
The item type of this PCD can only be "DYNAMIC".</HelpText>
</PcdEntry>
<PcdEntry>
@@ -333,8 +329,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<DatumType>VOID*</DatumType>
<ValidUsage>FIXED_AT_BUILD PATCHABLE_IN_MODULE</ValidUsage>
<DefaultValue>L"64!64"</DefaultValue>
- <HelpText>This PCD defines the memory size of simulated machine. Simulator will allocate
+ <HelpText>This PCD defines the memory size of simulated machine. Simulator will allocate
the size of PcdUnixMemorySizeForSecMain in host platform.</HelpText>
</PcdEntry>
+ <PcdEntry>
+ <C_Name>PcdUnixSerialPort</C_Name>
+ <Token>0x00001002</Token>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>VOID*</DatumType>
+ <ValidUsage>DYNAMIC</ValidUsage>
+ <DefaultValue>L"/dev/ttyS0"</DefaultValue>
+ <HelpText>Simulation serial IO port</HelpText>
+ </PcdEntry>
</PcdDeclarations>
-</PackageSurfaceArea>
+</PackageSurfaceArea> \ No newline at end of file
diff --git a/EdkUnixPkg/Include/Protocol/UnixIo.h b/EdkUnixPkg/Include/Protocol/UnixIo.h
index 2d8e9fab7d..1758ecb7c4 100644
--- a/EdkUnixPkg/Include/Protocol/UnixIo.h
+++ b/EdkUnixPkg/Include/Protocol/UnixIo.h
@@ -70,6 +70,16 @@ extern EFI_GUID gEfiUnixPhysicalDisksGuid;
extern EFI_GUID gEfiUnixFileSystemGuid;
//
+// EFI_WIN_NT_SERIAL_PORT
+//
+#define EFI_UNIX_SERIAL_PORT_GUID \
+ { \
+ 0x6d3a727d, 0x66c8, 0x4d19, {0x87, 0xe6, 0x2, 0x15, 0x86, 0x14, 0x90, 0xf3} \
+ }
+
+extern EFI_GUID gEfiUnixSerialPortGuid;
+
+//
// EFI_UNIX_UGA
//
#define EFI_UNIX_UGA_GUID \
diff --git a/EdkUnixPkg/Include/Protocol/UnixThunk.h b/EdkUnixPkg/Include/Protocol/UnixThunk.h
index aabb9b130d..1fa4e90204 100644
--- a/EdkUnixPkg/Include/Protocol/UnixThunk.h
+++ b/EdkUnixPkg/Include/Protocol/UnixThunk.h
@@ -28,6 +28,7 @@ Abstract:
#ifndef _UNIX_THUNK_H_
#define _UNIX_THUNK_H_
+#include <sys/termios.h>
#define EFI_UNIX_THUNK_PROTOCOL_GUID \
{ \
@@ -137,6 +138,43 @@ typedef
EFI_STATUS
(*UnixUgaCreate)(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo,
CONST CHAR16 *Title);
+
+typedef
+int
+(*UnixTcflush) (int fildes, int queue_selector);
+
+typedef
+void
+(*UnixPerror) (__const char *__s);
+
+typedef
+void
+(*UnixPrintf) (const char* format, ...);
+
+typedef
+int
+(*UnixIoCtl) (int fd, unsigned long int __request, ...);
+
+typedef
+int
+(*UnixFcntl) (int __fd, int __cmd, ...);
+
+typedef
+int
+(*UnixCfsetispeed) (struct termios *__termios_p, speed_t __speed);
+
+typedef
+int
+(*UnixCfsetospeed) (struct termios *__termios_p, speed_t __speed);
+
+typedef
+int
+(*UnixTcgetattr) (int __fd, struct termios *__termios_p);
+
+typedef
+int
+(*UnixTcsetattr) (int __fd, int __optional_actions,
+ __const struct termios *__termios_p);
//
//
@@ -147,14 +185,14 @@ EFI_STATUS
typedef struct _EFI_UNIX_THUNK_PROTOCOL {
UINT64 Signature;
- UnixSleep Sleep;
+ UnixSleep Sleep;
UnixExit Exit;
- UnixSetTimer SetTimer;
- UnixGetLocalTime GetLocalTime;
+ UnixSetTimer SetTimer;
+ UnixGetLocalTime GetLocalTime;
UnixGmTime GmTime;
UnixGetTimeZone GetTimeZone;
UnixGetDayLight GetDayLight;
- UnixPoll Poll;
+ UnixPoll Poll;
UnixRead Read;
UnixWrite Write;
UnixGetenv Getenv;
@@ -177,9 +215,16 @@ typedef struct _EFI_UNIX_THUNK_PROTOCOL {
UnixFSync FSync;
UnixChmod Chmod;
UnixUTime UTime;
-
- UnixUgaCreate UgaCreate;
-
+ UnixTcflush Tcflush;
+ UnixUgaCreate UgaCreate;
+ UnixPerror Perror;
+ UnixPrintf Printf;
+ UnixIoCtl IoCtl;
+ UnixFcntl Fcntl;
+ UnixCfsetispeed Cfsetispeed;
+ UnixCfsetospeed Cfsetospeed;
+ UnixTcgetattr Tcgetattr;
+ UnixTcsetattr Tcsetattr;
} EFI_UNIX_THUNK_PROTOCOL;
extern EFI_GUID gEfiUnixThunkProtocolGuid;
diff --git a/EdkUnixPkg/Sec/UnixThunk.c b/EdkUnixPkg/Sec/UnixThunk.c
index c1988faf59..9d74b5b8c3 100644
--- a/EdkUnixPkg/Sec/UnixThunk.c
+++ b/EdkUnixPkg/Sec/UnixThunk.c
@@ -37,7 +37,8 @@ Abstract:
#include <time.h>
#include <signal.h>
#include <string.h>
-#include <stdlib.h>
+#include <stdlib.h>
+#include <termio.h>
static int settimer_initialized;
static struct timeval settimer_timeval;
@@ -187,8 +188,16 @@ EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
fsync,
chmod,
utime,
-
- UgaCreate,
+ tcflush,
+ UgaCreate,
+ perror,
+ printf,
+ ioctl,
+ fcntl,
+ cfsetispeed,
+ cfsetospeed,
+ tcgetattr,
+ tcsetattr
};
diff --git a/EdkUnixPkg/Unix.fpd b/EdkUnixPkg/Unix.fpd
index c48a5e78c6..012b70b1c5 100644
--- a/EdkUnixPkg/Unix.fpd
+++ b/EdkUnixPkg/Unix.fpd
@@ -6938,7 +6938,7 @@
<TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
<DatumType>UINT32</DatumType>
<MaxDatumSize>4</MaxDatumSize>
- <Value>0x80000000</Value>
+ <Value>0x80000040</Value>
</PcdData>
<PcdData ItemType="FEATURE_FLAG">
<C_Name>PcdComponentNameDisable</C_Name>
@@ -7028,6 +7028,14 @@
<MaxDatumSize>4</MaxDatumSize>
<Value>320</Value>
</PcdData>
+ <PcdData ItemType="DYNAMIC">
+ <C_Name>PcdUnixSerialPort</C_Name>
+ <Token>0x00001002</Token>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>VOID*</DatumType>
+ <MaxDatumSize>20</MaxDatumSize>
+ <Value>L"/dev/ttyS0"</Value>
+ </PcdData>
</PcdBuildDefinition>
<ModuleSaBuildOptions>
<FvBinding>FV_RECOVERY</FvBinding>
@@ -7646,6 +7654,131 @@
<FfsFormatKey>Logo</FfsFormatKey>
</ModuleSaBuildOptions>
</ModuleSA>
+ <!--Mod: UnixSerialIo Type: UEFI_DRIVER Path: EdkUnixPkg\Dxe\UnixThunk\Bus\SerialIo\UnixSerialIo.msa-->
+ <ModuleSA ModuleGuid="600F2BF2-63A7-48ca-9FD0-A3450B87EE05" ModuleVersion="1.0" PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835" PackageVersion="0.3" SupArchList="IA32">
+ <Libraries>
+ <!--Pkg: MdePkg Mod: BaseLib Path: MdePkg\Library\BaseLib\BaseLib.msa-->
+ <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: DxeMemoryAllocationLib Path: MdePkg\Library\DxeMemoryAllocationLib\DxeMemoryAllocationLib.msa-->
+ <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: UefiDriverEntryPoint Path: MdePkg\Library\UefiDriverEntryPoint\UefiDriverEntryPoint.msa-->
+ <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: UefiLib Path: MdePkg\Library\UefiLib\UefiLib.msa-->
+ <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: UefiDriverModelLib Path: MdePkg\Library\UefiDriverModelLib\UefiDriverModelLib.msa-->
+ <Instance ModuleGuid="52af22ae-9901-4484-8cdc-622dd5838b09" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: UefiBootServicesTableLib Path: MdePkg\Library\UefiBootServicesTableLib\UefiBootServicesTableLib.msa-->
+ <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: BaseMemoryLib Path: MdePkg\Library\BaseMemoryLib\BaseMemoryLib.msa-->
+ <Instance ModuleGuid="fd44e603-002a-4b29-9f5f-529e815b6165" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: BaseTimerLibNullTemplate Path: MdePkg\Library\BaseTimerLibNullTemplate\BaseTimerLibNullTemplate.msa-->
+ <Instance ModuleGuid="f4731d79-537e-4505-bd52-c03f9b1f6b89" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: PeiDxeDebugLibReportStatusCode Path: MdePkg\Library\PeiDxeDebugLibReportStatusCode\PeiDxeDebugLibReportStatusCode.msa-->
+ <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: DxeReportStatusCodeLib Path: MdePkg\Library\DxeReportStatusCodeLib\DxeReportStatusCodeLib.msa-->
+ <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: BasePrintLib Path: MdePkg\Library\BasePrintLib\BasePrintLib.msa-->
+ <Instance ModuleGuid="a86fbfca-0183-4eeb-aa8a-762e3b7da1f3" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: UefiDevicePathLib Path: MdePkg\Library\UefiDevicePathLib\UefiDevicePathLib.msa-->
+ <Instance ModuleGuid="91c1677a-e57f-4191-8b8e-eb7711a716e0" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ <!--Pkg: MdePkg Mod: DxePcdLib Path: MdePkg\Library\DxePcdLib\DxePcdLib.msa-->
+ <Instance ModuleGuid="af97eb89-4cc6-45f8-a514-ca025b346480" ModuleVersion="1.0" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec" PackageVersion="0.3"/>
+ </Libraries>
+ <PcdBuildDefinition>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumUnicodeStringLength</C_Name>
+ <Token>0x00000001</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumAsciiStringLength</C_Name>
+ <Token>0x00000002</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumLinkedListLength</C_Name>
+ <Token>0x00000003</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdSpinLockTimeout</C_Name>
+ <Token>0x00000004</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>10000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdUefiLibMaxPrintBufferSize</C_Name>
+ <Token>0x101</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>320</Value>
+ </PcdData>
+ <PcdData ItemType="FEATURE_FLAG">
+ <C_Name>PcdComponentNameDisable</C_Name>
+ <Token>0x0000000d</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>BOOLEAN</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>FALSE</Value>
+ </PcdData>
+ <PcdData ItemType="FEATURE_FLAG">
+ <C_Name>PcdDriverDiagnosticsDisable</C_Name>
+ <Token>0x0000000e</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>BOOLEAN</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>FALSE</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugPropertyMask</C_Name>
+ <Token>0x00000005</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x0f</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugClearMemoryValue</C_Name>
+ <Token>0x00000008</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0xAF</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugPrintErrorLevel</C_Name>
+ <Token>0x00000006</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>0x80000040</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdReportStatusCodePropertyMask</C_Name>
+ <Token>0x00000007</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x06</Value>
+ </PcdData>
+ </PcdBuildDefinition>
+ <ModuleSaBuildOptions>
+ <FvBinding>FV_RECOVERY</FvBinding>
+ <FfsFormatKey>BS_DRIVER</FfsFormatKey>
+ </ModuleSaBuildOptions>
+ </ModuleSA>
</FrameworkModules>
<DynamicPcdBuildDefinitions>
<PcdBuildData ItemType="DYNAMIC">
@@ -7802,6 +7935,17 @@
<Value>L"64!64"</Value>
</SkuInfo>
</PcdBuildData>
+ <PcdBuildData ItemType="DYNAMIC">
+ <C_Name>PcdUnixSerialPort</C_Name>
+ <Token>0x00001002</Token>
+ <TokenSpaceGuidCName>gEfiEdkUnixPkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>VOID*</DatumType>
+ <MaxDatumSize>20</MaxDatumSize>
+ <SkuInfo>
+ <SkuId>0</SkuId>
+ <Value>L"/dev/ttyS0"</Value>
+ </SkuInfo>
+ </PcdBuildData>
</DynamicPcdBuildDefinitions>
<BuildOptions>
<Options>
@@ -7884,6 +8028,7 @@
<Module ModuleGuid="961578FE-B6B7-44c3-AF35-6BC705CD2B1F" PackageGuid="0fd7197b-9bde-44fe-a7e4-d2177a9922e5" Arch="IA32"/>
<Module ModuleGuid="6987936E-ED34-44db-AE97-1FA5E4ED2116" PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d" Arch="IA32"/>
<Module ModuleGuid="f330834e-8985-11db-a295-0040d02b1835" ModuleVersion="1.0" PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835" PackageVersion="0.3" Arch="IA32"/>
+ <Module ModuleGuid="600F2BF2-63A7-48ca-9FD0-A3450B87EE05" ModuleVersion="1.0" PackageGuid="f2805c44-8985-11db-9e98-0040d02b1835" PackageVersion="0.3" Arch="IA32"/>
</IncludeModules>
</UserExtensions>
<Ffs FfsKey="APPLICATION">