summaryrefslogtreecommitdiff
path: root/IntelFrameworkModulePkg
diff options
context:
space:
mode:
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-10 09:38:02 +0000
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-10 09:38:02 +0000
commit637ff81988c4fab871c5293a931d866ec051a107 (patch)
tree7d926bd34d3986b4cb39e53d165631722d45a3b6 /IntelFrameworkModulePkg
parent99bda0fd20817a768d596eda6d71b1f0e6e7d784 (diff)
downloadedk2-platforms-637ff81988c4fab871c5293a931d866ec051a107.tar.xz
Import IsaSerialDxe in IntelFrameworkModulePkg.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3170 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'IntelFrameworkModulePkg')
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.c226
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.h155
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf111
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.msa97
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c1902
-rw-r--r--IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h577
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc2
7 files changed, 3070 insertions, 0 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.c
new file mode 100644
index 0000000000..2156c1a130
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.c
@@ -0,0 +1,226 @@
+/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
+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.
+
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "Serial.h"
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gIsaSerialComponentName = {
+ IsaSerialComponentNameGetDriverName,
+ IsaSerialComponentNameGetControllerName,
+ "eng"
+};
+
+STATIC EFI_UNICODE_STRING_TABLE mIsaSerialDriverNameTable[] = {
+ {
+ "eng",
+ L"ISA Serial Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+EFI_STATUS
+EFIAPI
+IsaSerialComponentNameGetDriverName (
+ 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,
+ gIsaSerialComponentName.SupportedLanguages,
+ mIsaSerialDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialComponentNameGetControllerName (
+ 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;
+ SERIAL_DEV *SerialDevice;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gSerialControllerDriver.DriverBindingHandle,
+ &gEfiIsaIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Get the Block I/O Protocol on Controller
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSerialIoProtocolGuid,
+ (VOID **) &SerialIo,
+ gSerialControllerDriver.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,
+ gIsaSerialComponentName.SupportedLanguages,
+ SerialDevice->ControllerNameTable,
+ ControllerName
+ );
+}
+
+VOID
+AddName (
+ IN SERIAL_DEV *SerialDevice,
+ IN EFI_ISA_IO_PROTOCOL *IsaIo
+ )
+/*++
+
+ Routine Description:
+
+ Add the component name for the serial io device
+
+ Arguments:
+
+ SerialDevice - A pointer to the SERIAL_DEV instance.
+ IsaIo - A pointer to the EFI_ISA_IO_PROTOCOL or EFI_LIGHT_ISA_IO_PROTOCOL instance.
+
+ Returns:
+
+ None
+
+--*/
+{
+ CHAR16 SerialPortName[sizeof (SERIAL_PORT_NAME)];
+
+ StrCpy (SerialPortName, L"ISA Serial Port # ");
+ SerialPortName[sizeof (SERIAL_PORT_NAME) - 2] = (CHAR16) (L'0' + (UINT8) IsaIo->ResourceList->Device.UID);
+ AddUnicodeString (
+ "eng",
+ gIsaSerialComponentName.SupportedLanguages,
+ &SerialDevice->ControllerNameTable,
+ (CHAR16 *) SerialPortName
+ );
+}
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.h
new file mode 100644
index 0000000000..d17561aa38
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/ComponentName.h
@@ -0,0 +1,155 @@
+/*++
+
+Copyright (c) 2006 - 2007, 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.
+
+
+Module Name:
+
+ ComponentName.h
+
+Abstract:
+
+
+Revision History:
+
+--*/
+
+#ifndef _SERIAL_COMPONENT_NAME_H
+#define _SERIAL_COMPONENT_NAME_H
+
+#define SERIAL_PORT_NAME "ISA Serial Port # "
+#define ADD_SERIAL_NAME(x, y) AddName ((x), (y))
+
+extern EFI_COMPONENT_NAME_PROTOCOL gIsaSerialComponentName;
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+IsaSerialComponentNameGetDriverName (
+ 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.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+IsaSerialComponentNameGetControllerName (
+ 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.
+
+--*/
+;
+
+VOID
+AddName (
+ IN SERIAL_DEV *SerialDevice,
+ IN EFI_ISA_IO_PROTOCOL *IsaIo
+ )
+/*++
+
+ Routine Description:
+
+ Add the component name for the serial io device
+
+ Arguments:
+
+ SerialDevice - A pointer to the SERIAL_DEV instance.
+ IsaIo - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+
+ Returns:
+
+ None
+
+--*/
+;
+
+#endif
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf
new file mode 100644
index 0000000000..119c9b9261
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf
@@ -0,0 +1,111 @@
+#/** @file
+# Component description file for IsaSerial module.
+#
+# Serial driver for standard UARTS on an ISA bus.
+# Copyright (c) 2006 - 2007, 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.
+#
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IsaSerial
+ FILE_GUID = 93B80003-9FB3-11d4-9A3A-0090273FC14D
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+ ENTRY_POINT = InitializeIsaSerial
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gSerialControllerDriver
+# COMPONENT_NAME = gIsaSerialComponentName
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources.common]
+ ComponentName.c
+ ComponentName.h
+ serial.h
+ serial.c
+
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+# this module.
+#
+################################################################################
+
+[LibraryClasses]
+ PcdLib
+ ReportStatusCodeLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ DevicePathLib
+ UefiLib
+ BaseLib
+ UefiDriverEntryPoint
+ DebugLib
+
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+# that this module uses or produces.
+#
+################################################################################
+
+[Protocols]
+ gEfiIsaIoProtocolGuid # PROTOCOL TO_START
+ gEfiSerialIoProtocolGuid # PROTOCOL BY_START
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START
+
+
+################################################################################
+#
+# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ PcdNtEmulatorEnable|gEfiMdeModulePkgTokenSpaceGuid
+
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.msa b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.msa
new file mode 100644
index 0000000000..4ca5683ddc
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.msa
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd" xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>IsaSerial</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>93B80003-9FB3-11d4-9A3A-0090273FC14D</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for IsaSerial module.</Abstract>
+ <Description>Serial driver for standard UARTS on an ISA bus.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation.</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>IsaSerial</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>ReportStatusCodeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>serial.c</Filename>
+ <Filename>serial.h</Filename>
+ <Filename>ComponentName.h</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiSerialIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiIsaIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gSerialControllerDriver</DriverBinding>
+ <ComponentName>gIsaSerialComponentName</ComponentName>
+ </Extern>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdNtEmulatorEnable</C_Name>
+ <TokenSpaceGuidCName>gEfiEdkModulePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>If this PCD is set as TRUE, NT emulator will be endabled.</HelpText>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea> \ No newline at end of file
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
new file mode 100644
index 0000000000..b21f635fee
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
@@ -0,0 +1,1902 @@
+/**@file
+ Serial driver for standard UARTS on an ISA bus.
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
+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.
+
+**/
+
+#include "Serial.h"
+
+//
+// ISA Serial Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver = {
+ SerialControllerDriverSupported,
+ SerialControllerDriverStart,
+ SerialControllerDriverStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+/**
+ The user Entry Point for module IsaSerial. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeIsaSerial(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallAllDriverProtocols (
+ ImageHandle,
+ SystemTable,
+ &gSerialControllerDriver,
+ ImageHandle,
+ &gIsaSerialComponentName,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Check to see if this driver supports the given controller
+
+ Arguments:
+
+ This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of the controller to test.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - This driver can support the given controller
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+ UART_DEVICE_PATH UartNode;
+
+ //
+ // Ignore the RemainingDevicePath
+ //
+ //
+ // 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
+ );
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Use the ISA I/O Protocol to see if Controller is standard ISA UART that
+ // can be managed by this driver.
+ //
+ Status = EFI_SUCCESS;
+ if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x501)) {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+ }
+ //
+ // 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 ||
+ sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode)
+ ) {
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Start to management the controller passed in
+
+ Arguments:
+
+ This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of the controller to test.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - Driver is started successfully
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+ SERIAL_DEV *SerialDevice;
+ UINTN Index;
+ UART_DEVICE_PATH Node;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+ UINTN EntryCount;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+
+ 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;
+ }
+ //
+ // Report status code enable the serial
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_ENABLE | EFI_PERIPHERAL_SERIAL_PORT,
+ ParentDevicePath
+ );
+
+ //
+ // Grab the IO abstraction we need to get any work done
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ &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,
+ (EFI_PARITY_TYPE) Node.Parity,
+ Node.DataBits,
+ (EFI_STOP_BITS_TYPE) Node.StopBits
+ );
+ }
+ break;
+ }
+ }
+
+ gBS->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->IsaIo = IsaIo;
+ SerialDevice->ParentDevicePath = ParentDevicePath;
+ SerialDevice->ControllerNameTable = NULL;
+
+ ADD_SERIAL_NAME (SerialDevice, IsaIo);
+
+ for (Index = 0; SerialDevice->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {
+ if (SerialDevice->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {
+ SerialDevice->BaseAddress = (UINT16) SerialDevice->IsaIo->ResourceList->ResourceItem[Index].StartRange;
+ }
+ }
+ //
+ // Report status code the serial present
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_PRESENCE_DETECT | EFI_PERIPHERAL_SERIAL_PORT,
+ ParentDevicePath
+ );
+
+ if (!IsaSerialPortPresent (SerialDevice)) {
+ Status = EFI_DEVICE_ERROR;
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ EFI_P_EC_NOT_DETECTED | EFI_PERIPHERAL_SERIAL_PORT,
+ ParentDevicePath
+ );
+ goto Error;
+ }
+
+ SerialDevice->Signature = SERIAL_DEV_SIGNATURE;
+ SerialDevice->Type = UART16550A;
+ 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 = SERIAL_IO_INTERFACE_REVISION;
+ SerialDevice->SerialIo.Reset = IsaSerialReset;
+ SerialDevice->SerialIo.SetAttributes = IsaSerialSetAttributes;
+ SerialDevice->SerialIo.SetControl = IsaSerialSetControl;
+ SerialDevice->SerialIo.GetControl = IsaSerialGetControl;
+ SerialDevice->SerialIo.Write = IsaSerialWrite;
+ SerialDevice->SerialIo.Read = IsaSerialRead;
+ 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)) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ EFI_P_EC_CONTROLLER_ERROR | EFI_PERIPHERAL_SERIAL_PORT,
+ ParentDevicePath
+ );
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (SerialDevice) {
+ if (SerialDevice->DevicePath) {
+ gBS->FreePool (SerialDevice->DevicePath);
+ }
+
+ FreeUnicodeStringTable (SerialDevice->ControllerNameTable);
+ gBS->FreePool (SerialDevice);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Disconnect this driver with the controller, uninstall related protocol instance
+
+ Arguments:
+
+ This - A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of the controller to test.
+ NumberOfChildren - Number of child device.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - Operation successfully
+ EFI_DEVICE_ERROR - Cannot stop the driver successfully
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ EFI_SERIAL_IO_PROTOCOL *SerialIo;
+ SERIAL_DEV *SerialDevice;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &DevicePath
+ );
+
+ //
+ // Report the status code disable the serial
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_DISABLE | EFI_PERIPHERAL_SERIAL_PORT,
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ 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,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ SerialDevice->DevicePath,
+ &gEfiSerialIoProtocolGuid,
+ &SerialDevice->SerialIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ if (SerialDevice->DevicePath) {
+ gBS->FreePool (SerialDevice->DevicePath);
+ }
+
+ FreeUnicodeStringTable (SerialDevice->ControllerNameTable);
+ gBS->FreePool (SerialDevice);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsaSerialFifoFull (
+ IN SERIAL_DEV_FIFO *Fifo
+ )
+/*++
+
+ Routine Description:
+
+ Detect whether specific FIFO is full or not
+
+ Arguments:
+
+ 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 - 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 - A pointer to the Data Structure SERIAL_DEV_FIFO
+ Data - the data added to FIFO
+
+ Returns:
+
+ EFI_SUCCESS - Add data to specific FIFO successfully
+ EFI_OUT_OF_RESOURCE - Failed to add data because FIFO is already full
+
+--*/
+{
+ //
+ // 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 - A pointer to the Data Structure SERIAL_DEV_FIFO
+ Data - the data removed from FIFO
+
+ Returns:
+ EFI_SUCCESS - Remove data from specific FIFO successfully
+ EFI_OUT_OF_RESOURCE - Failed to remove data because FIFO is empty
+
+--*/
+{
+ //
+ // 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;
+}
+
+EFI_STATUS
+IsaSerialReceiveTransmit (
+ IN SERIAL_DEV *SerialDevice
+ )
+/*++
+
+ Routine Description:
+
+ Reads and writes all avaliable data.
+
+ Arguments:
+
+ SerialDevice - The device to flush
+
+ Returns:
+
+ EFI_SUCCESS - Data was read/written successfully.
+ EFI_OUT_OF_RESOURCE - Failed because software receive FIFO is full. Note, when
+ this happens, pending writes are not done.
+
+--*/
+{
+ 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 = IsaSerialFifoFull (&SerialDevice->Receive);
+ if (!IsaSerialFifoEmpty (&SerialDevice->Transmit)) {
+ IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
+ if (ReceiveFifoFull) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IsaSerialFifoAdd (&SerialDevice->Receive, Data);
+ }
+ } while (!IsaSerialFifoEmpty (&SerialDevice->Transmit));
+ } else {
+ ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);
+ do {
+ Lsr.Data = READ_LSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+
+ if (FeaturePcdGet (PcdNtEmulatorEnable)) {
+ //
+ // 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;
+ }
+ //
+ // Flush incomming data to prevent a an overrun during a long write
+ //
+ if (Lsr.Bits.DR && !ReceiveFifoFull) {
+ ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);
+ if (!ReceiveFifoFull) {
+ if (Lsr.Bits.FIFOE || Lsr.Bits.OE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,
+ SerialDevice->DevicePath
+ );
+ if (Lsr.Bits.FIFOE || Lsr.Bits.PE || Lsr.Bits.FE || Lsr.Bits.BI) {
+ Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ continue;
+ }
+ }
+ //
+ // Make sure the receive data will not be missed, Assert DTR
+ //
+ if (SerialDevice->HardwareFlowControl) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.DTRC &= 0;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
+
+ Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+
+ //
+ // Deassert DTR
+ //
+ if (SerialDevice->HardwareFlowControl) {
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.DTRC |= 1;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
+
+ IsaSerialFifoAdd (&SerialDevice->Receive, Data);
+
+ continue;
+ } else {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER | EFI_PERIPHERAL_SERIAL_PORT,
+ SerialDevice->DevicePath
+ );
+ }
+ }
+ //
+ // Do the write
+ //
+ if (Lsr.Bits.THRE && !IsaSerialFifoEmpty (&SerialDevice->Transmit)) {
+ //
+ // Make sure the transmit data will not be missed
+ //
+ if (SerialDevice->HardwareFlowControl) {
+ //
+ // Send RTS
+ //
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.RTS |= 1;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ //
+ // Wait for CTS
+ //
+ TimeOut = 0;
+ Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ while (!Msr.Bits.CTS) {
+ gBS->Stall (TIMEOUT_STALL_INTERVAL);
+ TimeOut++;
+ if (TimeOut > 5) {
+ break;
+ }
+
+ Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ }
+
+ if (Msr.Bits.CTS) {
+ IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
+ WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
+ }
+ }
+ //
+ // write the data out
+ //
+ if (!SerialDevice->HardwareFlowControl) {
+ IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);
+ WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);
+ }
+ //
+ // Make sure the transmit data will not be missed
+ //
+ if (SerialDevice->HardwareFlowControl) {
+ //
+ // Assert RTS
+ //
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.RTS &= 0;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+ }
+ }
+ } while (Lsr.Bits.THRE && !IsaSerialFifoEmpty (&SerialDevice->Transmit));
+ }
+
+ return EFI_SUCCESS;
+}
+//
+// Interface Functions
+//
+EFI_STATUS
+EFIAPI
+IsaSerialReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ )
+/*++
+
+ Routine Description:
+
+ Reset serial device
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+
+ Returns:
+
+ EFI_SUCCESS - Reset successfully
+ EFI_DEVICE_ERROR - Failed to reset
+
+--*/
+{
+ 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);
+
+ //
+ // Report the status code reset the serial
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_RESET | EFI_PERIPHERAL_SERIAL_PORT,
+ SerialDevice->DevicePath
+ );
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Make sure DLAB is 0.
+ //
+ Lcr.Data = READ_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Lcr.Bits.DLAB = 0;
+ WRITE_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Lcr.Data);
+
+ //
+ // Turn off all interrupts
+ //
+ Ier.Data = READ_IER (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Ier.Bits.RAVIE = 0;
+ Ier.Bits.THEIE = 0;
+ Ier.Bits.RIE = 0;
+ Ier.Bits.MIE = 0;
+ WRITE_IER (SerialDevice->IsaIo, SerialDevice->BaseAddress, Ier.Data);
+
+ //
+ // Disable the FIFO.
+ //
+ Fcr.Bits.TRFIFOE = 0;
+ WRITE_FCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Fcr.Data);
+
+ //
+ // Turn off loopback and disable device interrupt.
+ //
+ Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ Mcr.Bits.OUT1 = 0;
+ Mcr.Bits.OUT2 = 0;
+ Mcr.Bits.LME = 0;
+ WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+
+ //
+ // Clear the scratch pad register
+ //
+ WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0);
+
+ //
+ // Go set the current attributes
+ //
+ Status = This->SetAttributes (
+ This,
+ This->Mode->BaudRate,
+ This->Mode->ReceiveFifoDepth,
+ This->Mode->Timeout,
+ (EFI_PARITY_TYPE) This->Mode->Parity,
+ (UINT8) This->Mode->DataBits,
+ (EFI_STOP_BITS_TYPE) 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;
+ }
+ //
+ // for 16550A enable FIFO, 16550 disable FIFO
+ //
+ Fcr.Bits.TRFIFOE = 1;
+ Fcr.Bits.RESETRF = 1;
+ Fcr.Bits.RESETTF = 1;
+ WRITE_FCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Fcr.Data);
+
+ //
+ // Reset the software FIFO
+ //
+ 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;
+
+ gBS->RestoreTPL (Tpl);
+
+ //
+ // Device reset is complete
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialSetAttributes (
+ 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:
+
+ Set new attributes to a serial device
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+ BaudRate - The baudrate of the serial device
+ ReceiveFifoDepth - The depth of receive FIFO buffer
+ Timeout - The request timeout for a single char
+ Parity - The type of parity used in serial device
+ DataBits - Number of databits used in serial device
+ StopBits - Number of stopbits used in serial device
+
+ Returns:
+
+ EFI_SUCCESS - The new attributes were set
+ EFI_INVALID_PARAMETERS - One or more attributes have an unsupported value
+ EFI_UNSUPPORTED - Data Bits can not set to 5 or 6
+ EFI_DEVICE_ERROR - The serial device is not functioning correctly (no return)
+
+--*/
+{
+ 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);
+
+ //
+ // 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 = (EFI_STOP_BITS_TYPE) 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;
+ }
+
+ //
+ // 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->IsaIo, SerialDevice->BaseAddress);
+ Lcr.Bits.DLAB = 1;
+ WRITE_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Lcr.Data);
+
+ //
+ // Write the divisor to the serial port
+ //
+ WRITE_DLL (SerialDevice->IsaIo, SerialDevice->BaseAddress, (UINT8) (Divisor & 0xff));
+ WRITE_DLM (SerialDevice->IsaIo, SerialDevice->BaseAddress, (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->IsaIo, SerialDevice->BaseAddress, 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) {
+ gBS->FreePool (SerialDevice->DevicePath);
+ }
+
+ SerialDevice->DevicePath = NewDevicePath;
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialSetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ )
+/*++
+
+ Routine Description:
+
+ Set Control Bits
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+ Control - Control bits that can be settable
+
+ Returns:
+
+ EFI_SUCCESS - New Control bits were set successfully
+ EFI_UNSUPPORTED - The Control bits wanted to set are not supported
+
+--*/
+{
+ 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->IsaIo, SerialDevice->BaseAddress);
+ 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->IsaIo, SerialDevice->BaseAddress, Mcr.Data);
+
+ if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {
+ SerialDevice->SoftwareLoopbackEnable = TRUE;
+ }
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialGetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ )
+/*++
+
+ Routine Description:
+
+ Get ControlBits
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+ Control - Control signals of the serial device
+
+ Returns:
+
+ EFI_SUCCESS - Get Control signals successfully
+
+--*/
+{
+ 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->IsaIo, SerialDevice->BaseAddress);
+
+ 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->IsaIo, SerialDevice->BaseAddress);
+
+ 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
+ //
+ IsaSerialReceiveTransmit (SerialDevice);
+
+ if (IsaSerialFifoEmpty (&SerialDevice->Transmit)) {
+ *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;
+ }
+ //
+ // See if the Receive FIFO is empty.
+ //
+ IsaSerialReceiveTransmit (SerialDevice);
+
+ if (IsaSerialFifoEmpty (&SerialDevice->Receive)) {
+ *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;
+ }
+
+ if (SerialDevice->SoftwareLoopbackEnable) {
+ *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;
+ }
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialWrite (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+/*++
+
+ Routine Description:
+
+ Write the specified number of bytes to serial device
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+ BufferSize - On input the size of Buffer, on output the amount of
+ data actually written
+ Buffer - The buffer of data to write
+
+ Returns:
+
+ EFI_SUCCESS - The data were written successfully
+ EFI_DEVICE_ERROR - The device reported an error
+ EFI_TIMEOUT - The write operation was stopped due to timeout
+
+--*/
+{
+ SERIAL_DEV *SerialDevice;
+ UINT8 *CharBuffer;
+ UINT32 Index;
+ UINTN Elapsed;
+ UINTN ActualWrite;
+ EFI_TPL Tpl;
+
+ SerialDevice = SERIAL_DEV_FROM_THIS (This);
+ Elapsed = 0;
+ ActualWrite = 0;
+
+ if (*BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (!Buffer) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ EFI_P_EC_OUTPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,
+ SerialDevice->DevicePath
+ );
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ CharBuffer = (UINT8 *) Buffer;
+
+ for (Index = 0; Index < *BufferSize; Index++) {
+ IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);
+
+ while (IsaSerialReceiveTransmit (SerialDevice) != EFI_SUCCESS || !IsaSerialFifoEmpty (&SerialDevice->Transmit)) {
+ //
+ // 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;
+ gBS->RestoreTPL (Tpl);
+ return EFI_TIMEOUT;
+ }
+
+ gBS->Stall (TIMEOUT_STALL_INTERVAL);
+
+ Elapsed += TIMEOUT_STALL_INTERVAL;
+ }
+
+ ActualWrite++;
+ //
+ // Successful write so reset timeout
+ //
+ Elapsed = 0;
+ }
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaSerialRead (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+ Routine Description:
+
+ Read the specified number of bytes from serial device
+
+ Arguments:
+
+ This - Pointer to EFI_SERIAL_IO_PROTOCOL
+ BufferSize - On input the size of Buffer, on output the amount of
+ data returned in buffer
+ Buffer - The buffer to return the data into
+
+ Returns:
+
+ EFI_SUCCESS - The data were read successfully
+ EFI_DEVICE_ERROR - The device reported an error
+ EFI_TIMEOUT - The read operation was stopped due to timeout
+
+--*/
+{
+ 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;
+ }
+
+ Tpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = IsaSerialReceiveTransmit (SerialDevice);
+
+ if (EFI_ERROR (Status)) {
+ *BufferSize = 0;
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,
+ SerialDevice->DevicePath
+ );
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ CharBuffer = (UINT8 *) Buffer;
+ for (Index = 0; Index < *BufferSize; Index++) {
+ while (IsaSerialFifoRemove (&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 = IsaSerialReceiveTransmit (SerialDevice);
+ if (Status == EFI_DEVICE_ERROR) {
+ *BufferSize = Index;
+ gBS->RestoreTPL (Tpl);
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //
+ // Successful read so reset timeout
+ //
+ Elapsed = 0;
+ }
+
+ IsaSerialReceiveTransmit (SerialDevice);
+
+ gBS->RestoreTPL (Tpl);
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsaSerialPortPresent (
+ IN SERIAL_DEV *SerialDevice
+ )
+/*++
+
+ Routine Description:
+
+ Use scratchpad register to test if this serial port is present
+
+ Arguments:
+
+ SerialDevice - Pointer to serial device structure
+
+ Returns:
+
+ TRUE - The serial port is present
+ FALSE - The serial port is NOT present
+
+--*/
+{
+ UINT8 Temp;
+ BOOLEAN Status;
+
+ Status = TRUE;
+
+ //
+ // Save SCR reg
+ //
+ Temp = READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);
+ WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0xAA);
+
+ if (READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress) != 0xAA)
+ {
+ if (!FeaturePcdGet (PcdNtEmulatorEnable)) {
+ Status = FALSE;
+ }
+ }
+
+ WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0x55);
+
+ if (READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress) != 0x55)
+ {
+ if (!FeaturePcdGet (PcdNtEmulatorEnable)) {
+ Status = FALSE;
+ }
+ }
+ //
+ // Restore SCR
+ //
+ WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Temp);
+ return Status;
+}
+
+UINT8
+IsaSerialReadPort (
+ IN EFI_ISA_IO_PROTOCOL *IsaIo,
+ IN UINT16 BaseAddress,
+ IN UINT32 Offset
+ )
+/*++
+
+ Routine Description:
+
+ Use IsaIo protocol to read serial port
+
+ Arguments:
+
+ IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
+ BaseAddress - Serial port register group base address
+ Offset - Offset in register group
+
+ Returns:
+
+ Data read from serial port
+
+--*/
+{
+ UINT8 Data;
+
+ //
+ // Use IsaIo to access IO
+ //
+ IsaIo->Io.Read (
+ IsaIo,
+ EfiIsaIoWidthUint8,
+ BaseAddress + Offset,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+VOID
+IsaSerialWritePort (
+ IN EFI_ISA_IO_PROTOCOL *IsaIo,
+ IN UINT16 BaseAddress,
+ IN UINT32 Offset,
+ IN UINT8 Data
+ )
+/*++
+
+ Routine Description:
+
+ Use IsaIo protocol to write serial port
+
+ Arguments:
+
+ IsaIo - Pointer to EFI_ISA_IO_PROTOCOL instance
+ BaseAddress - Serial port register group base address
+ Offset - Offset in register group
+ Data - data which is to be written to some serial port register
+
+ Returns:
+
+ None
+
+--*/
+{
+ //
+ // Use IsaIo to access IO
+ //
+ IsaIo->Io.Write (
+ IsaIo,
+ EfiIsaIoWidthUint8,
+ BaseAddress + Offset,
+ 1,
+ &Data
+ );
+}
+
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h
new file mode 100644
index 0000000000..d06f728267
--- /dev/null
+++ b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.h
@@ -0,0 +1,577 @@
+/*++
+
+Copyright (c) 2006 - 2007, 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.
+
+
+Module Name:
+
+ serial.h
+
+Abstract:
+
+ Include for Serial Driver
+
+Revision History:
+
+--*/
+
+#ifndef _SERIAL_H
+#define _SERIAL_H
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+#include <FrameworkPei.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/IsaIo.h>
+#include <Protocol/SerialIo.h>
+#include <Protocol/DevicePath.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/PcdLib.h>
+//
+// Driver Binding Externs
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver;
+extern EFI_COMPONENT_NAME_PROTOCOL gIsaSerialComponentName;
+
+//
+// Internal Data Structures
+//
+#define SERIAL_DEV_SIGNATURE EFI_SIGNATURE_32 ('s', 'e', 'r', 'd')
+#define SERIAL_MAX_BUFFER_SIZE 16
+#define TIMEOUT_STALL_INTERVAL 10
+
+//
+// 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
+// BaseAddress UINT16: 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_ISA_IO_PROTOCOL *IsaIo;
+
+ UINT16 BaseAddress;
+ SERIAL_DEV_FIFO Receive;
+ SERIAL_DEV_FIFO Transmit;
+ BOOLEAN SoftwareLoopbackEnable;
+ BOOLEAN HardwareFlowControl;
+ EFI_UART_TYPE Type;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} SERIAL_DEV;
+
+#include "ComponentName.h"
+
+#define SERIAL_DEV_FROM_THIS(a) CR (a, SERIAL_DEV, SerialIo, SERIAL_DEV_SIGNATURE)
+
+//
+// Globale Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver;
+
+//
+// Serial Driver Defaults
+//
+#define SERIAL_PORT_DEFAULT_BAUD_RATE 115200
+#define SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH 1
+#define SERIAL_PORT_DEFAULT_TIMEOUT 1000000
+#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 0
+
+//
+// (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 100000000 // 100 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
+#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) IsaSerialReadPort (IO, B, SERIAL_REGISTER_RBR)
+#define READ_DLL(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_DLL)
+#define READ_DLM(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_DLM)
+#define READ_IER(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_IER)
+#define READ_IIR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_IIR)
+#define READ_LCR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_LCR)
+#define READ_MCR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_MCR)
+#define READ_LSR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_LSR)
+#define READ_MSR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_MSR)
+#define READ_SCR(IO, B) IsaSerialReadPort (IO, B, SERIAL_REGISTER_SCR)
+
+#define WRITE_THR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_THR, D)
+#define WRITE_DLL(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_DLL, D)
+#define WRITE_DLM(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_DLM, D)
+#define WRITE_IER(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_IER, D)
+#define WRITE_FCR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_FCR, D)
+#define WRITE_LCR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_LCR, D)
+#define WRITE_MCR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_MCR, D)
+#define WRITE_LSR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_LSR, D)
+#define WRITE_MSR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_MSR, D)
+#define WRITE_SCR(IO, B, D) IsaSerialWritePort (IO, B, SERIAL_REGISTER_SCR, D)
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+SerialControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Serial I/O Protocol Interface
+//
+EFI_STATUS
+EFIAPI
+IsaSerialReset (
+ IN EFI_SERIAL_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+IsaSerialSetAttributes (
+ 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
+EFIAPI
+IsaSerialSetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN UINT32 Control
+ );
+
+EFI_STATUS
+EFIAPI
+IsaSerialGetControl (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ OUT UINT32 *Control
+ );
+
+EFI_STATUS
+EFIAPI
+IsaSerialWrite (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+IsaSerialRead (
+ IN EFI_SERIAL_IO_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+//
+// Internal Functions
+//
+BOOLEAN
+IsaSerialPortPresent (
+ IN SERIAL_DEV *SerialDevice
+ );
+
+BOOLEAN
+IsaSerialFifoFull (
+ IN SERIAL_DEV_FIFO *Fifo
+ );
+
+BOOLEAN
+IsaSerialFifoEmpty (
+ IN SERIAL_DEV_FIFO *Fifo
+ );
+
+EFI_STATUS
+IsaSerialFifoAdd (
+ IN SERIAL_DEV_FIFO *Fifo,
+ IN UINT8 Data
+ );
+
+EFI_STATUS
+IsaSerialFifoRemove (
+ IN SERIAL_DEV_FIFO *Fifo,
+ OUT UINT8 *Data
+ );
+
+EFI_STATUS
+IsaSerialReceiveTransmit (
+ IN SERIAL_DEV *SerialDevice
+ );
+
+UINT8
+IsaSerialReadPort (
+ IN EFI_ISA_IO_PROTOCOL *IsaIo,
+ IN UINT16 BaseAddress,
+ IN UINT32 Offset
+ );
+
+VOID
+IsaSerialWritePort (
+ IN EFI_ISA_IO_PROTOCOL *IsaIo,
+ IN UINT16 BaseAddress,
+ IN UINT32 Offset,
+ IN UINT8 Data
+ );
+
+#endif
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
index 300f25169a..370b55ee6a 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
@@ -136,6 +136,7 @@
PcdIsaBusSupportDma|gEfiIntelFrameworkModulePkgTokenSpaceGuid|TRUE
PcdIsaBusOnlySupportSlaveDma|gEfiIntelFrameworkModulePkgTokenSpaceGuid|FALSE
PcdIsaBusSupportIsaMemory|gEfiIntelFrameworkModulePkgTokenSpaceGuid|TRUE
+ PcdNtEmulatorEnable|gEfiMdeModulePkgTokenSpaceGuid|FALSE
[PcdsFixedAtBuild.common]
PcdMaximumUnicodeStringLength|gEfiMdePkgTokenSpaceGuid|1000000
@@ -178,6 +179,7 @@
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaFloppy/Dxe/IsaFloppy.inf
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaFloppy/Pei/FloppyPeim.inf
+ $(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerial.inf
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboard.inf
$(WORKSPACE)/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.inf
$(WORKSPACE)/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf