]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Check in the IsaIoDxe device driver that consumes EFI_SIO_PROTOCOL to produce EFI_ISA...
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 19 Aug 2010 02:40:27 +0000 (02:40 +0000)
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 19 Aug 2010 02:40:27 +0000 (02:40 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10808 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.c [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.h [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.c [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.h [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.c [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.h [new file with mode: 0644]
IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf [new file with mode: 0644]
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc

diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..e4e77a9
--- /dev/null
@@ -0,0 +1,182 @@
+/** @file\r
+  UEFI Component Name(2) protocol implementation for Isa driver.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "IsaDriver.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gIsaIoComponentName = {\r
+  IsaIoComponentNameGetDriverName,\r
+  IsaIoComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIsaIoComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) IsaIoComponentNameGetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) IsaIoComponentNameGetControllerName,\r
+  "en"\r
+};\r
+\r
+\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIsaIoDriverNameTable[] = {\r
+  {\r
+    "eng;en",\r
+    L"ISA IO Driver"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mIsaIoDriverNameTable,\r
+           DriverName,\r
+           (BOOLEAN)(This == &gIsaIoComponentName)\r
+           );\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_HANDLE                   ChildHandle  OPTIONAL,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **ControllerName\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/ComponentName.h
new file mode 100644 (file)
index 0000000..7c52119
--- /dev/null
@@ -0,0 +1,148 @@
+/** @file\r
+  Header file for implementation of UEFI Component Name(2) protocol.\r
+\r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _COMPONENT_NAME_H_\r
+#define _COMPONENT_NAME_H_\r
+\r
+extern EFI_COMPONENT_NAME_PROTOCOL   gIsaIoComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL  gIsaIoComponentName2;\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_HANDLE                   ChildHandle  OPTIONAL,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **ControllerName\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.c b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.c
new file mode 100644 (file)
index 0000000..a9252f0
--- /dev/null
@@ -0,0 +1,339 @@
+/** @file\r
+  IsaIo UEFI driver.\r
+\r
+  Produce an instance of the ISA I/O Protocol for every SIO controller.\r
+  \r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "IsaDriver.h"\r
+\r
+//\r
+// IsaIo Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gIsaIoDriver = {\r
+  IsaIoDriverSupported,\r
+  IsaIoDriverStart,\r
+  IsaIoDriverStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+/**\r
+  The main entry point for the IsaIo driver.\r
+\r
+  @param[in] ImageHandle        The firmware allocated handle for the EFI image.  \r
+  @param[in] SystemTable        A pointer to the EFI System Table.\r
+  \r
+  @retval EFI_SUCCESS           The entry point is executed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  There was not enough memory in pool to install all the protocols.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeIsaIo (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gIsaIoDriver,\r
+             ImageHandle,\r
+             &gIsaIoComponentName,\r
+             &gIsaIoComponentName2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+/** \r
+  Tests to see if a controller can be managed by the IsaIo driver.\r
+\r
+  @param[in] This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.  \r
+  @param[in] Controller           The handle of the controller to test.\r
+  @param[in] RemainingDevicePath  A pointer to the remaining portion of a device path.\r
+  \r
+  @retval EFI_SUCCESS             The device is supported by this driver.\r
+  @retval EFI_ALREADY_STARTED     The device is already being managed by this driver.\r
+  @retval EFI_ACCESS_DENIED       The device is already being managed by a different driver \r
+                                  or an application that requires exclusive access.\r
+  @retval EFI_UNSUPPORTED         The device is is not supported by this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_SIO_PROTOCOL          *Sio;\r
+  EFI_HANDLE                PciHandle;\r
+\r
+  //\r
+  // Try to open EFI DEVICE PATH protocol on the controller\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &DevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Get the PciIo protocol from its parent controller.\r
+    //\r
+    Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &DevicePath, &PciHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      if ((DevicePathType (DevicePath) != ACPI_DEVICE_PATH) ||\r
+          ((DevicePathSubType (DevicePath) != ACPI_DP) && (DevicePathSubType (DevicePath) != ACPI_EXTENDED_DP))) {\r
+        Status = EFI_UNSUPPORTED;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Try to open the Super IO protocol on the controller\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiSioProtocolGuid,\r
+                  (VOID **) &Sio,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiSioProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle. \r
+  \r
+  The Start() function is designed to be invoked from the EFI boot service ConnectController(). \r
+  As a result, much of the error checking on the parameters to Start() has been moved into this \r
+  common boot service. It is legal to call Start() from other locations, but the following calling \r
+  restrictions must be followed or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE.\r
+  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+     EFI_DEVICE_PATH_PROTOCOL.\r
+  3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.  \r
+\r
+  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle     The handle of the controller to start. This handle \r
+                                   must support a protocol interface that supplies \r
+                                   an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path. \r
+                                   This parameter is ignored by device drivers, and is optional for bus drivers.\r
+\r
+  @retval EFI_SUCCESS              The device was started.\r
+  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.\r
+                                   Currently not implemented.\r
+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.\r
+  @retval Others                   The driver failded to start the device.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  EFI_PCI_IO_PROTOCOL                   *PciIo;\r
+  EFI_DEVICE_PATH_PROTOCOL              *DevicePath;\r
+  EFI_HANDLE                            PciHandle;\r
+  EFI_SIO_PROTOCOL                      *Sio;\r
+  ACPI_RESOURCE_HEADER_PTR              Resources;\r
+  EFI_DEVICE_PATH_PROTOCOL              *AcpiNode;\r
+  ISA_IO_DEVICE                         *IsaIoDevice;\r
+\r
+  PciIo = NULL;\r
+  Sio   = NULL;\r
+\r
+  //\r
+  // Open Device Path Protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &DevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Get the PciIo protocol from its parent controller.\r
+  //\r
+  AcpiNode = DevicePath;\r
+  Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &AcpiNode, &PciHandle);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // AcpiNode should point to the ACPI node now.\r
+    //\r
+    ASSERT ((DevicePathType (AcpiNode) == ACPI_DEVICE_PATH) &&\r
+            ((DevicePathSubType (AcpiNode) == ACPI_DP) || (DevicePathSubType (AcpiNode) == ACPI_EXTENDED_DP))\r
+           );\r
+\r
+    Status = gBS->HandleProtocol (PciHandle, &gEfiPciIoProtocolGuid, &PciIo);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Open Super IO Protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiSioProtocolGuid,\r
+                    (VOID **) &Sio,\r
+                    This->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                    );\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Fail due to LocateDevicePath(...) or OpenProtocol(Sio, BY_DRIVER)\r
+    //\r
+    return Status;\r
+  }\r
+\r
+  Status = Sio->GetResources (Sio, &Resources);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  IsaIoDevice = AllocatePool (sizeof (ISA_IO_DEVICE));\r
+  ASSERT (IsaIoDevice != NULL);\r
+\r
+  IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;\r
+  IsaIoDevice->PciIo     = PciIo;\r
+\r
+  //\r
+  // Initialize the ISA I/O instance structure\r
+  //\r
+  InitializeIsaIoInstance (IsaIoDevice, DevicePath, Resources);\r
+\r
+  //\r
+  // Install the ISA I/O protocol on the Controller handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Controller,\r
+                  &gEfiIsaIoProtocolGuid,\r
+                  &IsaIoDevice->IsaIo,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle. \r
+  \r
+  The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). \r
+  As a result, much of the error checking on the parameters to Stop() has been moved \r
+  into this common boot service. It is legal to call Stop() from other locations, \r
+  but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+     same driver's Start() function.\r
+  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+     EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+     Start() function, and the Start() function must have called OpenProtocol() on\r
+     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+  \r
+  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must \r
+                                support a bus specific I/O protocol for the driver \r
+                                to use to stop the device.\r
+  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.\r
+  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL \r
+                                if NumberOfChildren is 0.\r
+\r
+  @retval EFI_SUCCESS           The device was stopped.\r
+  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  * This,\r
+  IN  EFI_HANDLE                   Controller,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   * ChildHandleBuffer OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  ISA_IO_DEVICE                       *IsaIoDevice;\r
+  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiIsaIoProtocolGuid,\r
+                  (VOID **) &IsaIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);\r
+\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  Controller,\r
+                  &gEfiIsaIoProtocolGuid,\r
+                  &IsaIoDevice->IsaIo,\r
+                  NULL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->CloseProtocol (\r
+                    Controller,\r
+                    &gEfiSioProtocolGuid,\r
+                    This->DriverBindingHandle,\r
+                    Controller\r
+                    );\r
+    FreePool (IsaIoDevice->IsaIo.ResourceList);\r
+    FreePool (IsaIoDevice);\r
+  }\r
+\r
+   return Status;\r
+}
\ No newline at end of file
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.h b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaDriver.h
new file mode 100644 (file)
index 0000000..64f710b
--- /dev/null
@@ -0,0 +1,263 @@
+/** @file\r
+  The header file for ISA driver\r
+  \r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ISA_DRIVER_H_\r
+#define _ISA_DRIVER_H_\r
+\r
+\r
+#include <Uefi.h>\r
+\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/SuperIo.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/IsaIo.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/GenericMemoryTest.h>\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+#include "ComponentName.h"\r
+\r
+//\r
+// 8237 DMA registers\r
+//\r
+#define R_8237_DMA_BASE_CA_CH0                    0x00\r
+#define R_8237_DMA_BASE_CA_CH1                    0x02\r
+#define R_8237_DMA_BASE_CA_CH2                    0x04\r
+#define R_8237_DMA_BASE_CA_CH3                    0xd6\r
+#define R_8237_DMA_BASE_CA_CH5                    0xc4\r
+#define R_8237_DMA_BASE_CA_CH6                    0xc8\r
+#define R_8237_DMA_BASE_CA_CH7                    0xcc\r
+\r
+#define R_8237_DMA_BASE_CC_CH0                    0x01\r
+#define R_8237_DMA_BASE_CC_CH1                    0x03\r
+#define R_8237_DMA_BASE_CC_CH2                    0x05\r
+#define R_8237_DMA_BASE_CC_CH3                    0xd7\r
+#define R_8237_DMA_BASE_CC_CH5                    0xc6\r
+#define R_8237_DMA_BASE_CC_CH6                    0xca\r
+#define R_8237_DMA_BASE_CC_CH7                    0xce\r
+\r
+#define R_8237_DMA_MEM_LP_CH0                     0x87\r
+#define R_8237_DMA_MEM_LP_CH1                     0x83\r
+#define R_8237_DMA_MEM_LP_CH2                     0x81\r
+#define R_8237_DMA_MEM_LP_CH3                     0x82\r
+#define R_8237_DMA_MEM_LP_CH5                     0x8B\r
+#define R_8237_DMA_MEM_LP_CH6                     0x89\r
+#define R_8237_DMA_MEM_LP_CH7                     0x8A\r
+\r
+\r
+#define R_8237_DMA_COMMAND_CH0_3                  0x08\r
+#define R_8237_DMA_COMMAND_CH4_7                  0xd0\r
+#define   B_8237_DMA_COMMAND_GAP                  0x10\r
+#define   B_8237_DMA_COMMAND_CGE                  0x04\r
+\r
+\r
+#define R_8237_DMA_STA_CH0_3                      0xd8\r
+#define R_8237_DMA_STA_CH4_7                      0xd0\r
+\r
+#define R_8237_DMA_WRSMSK_CH0_3                   0x0a\r
+#define R_8237_DMA_WRSMSK_CH4_7                   0xd4\r
+#define   B_8237_DMA_WRSMSK_CMS                   0x04\r
+\r
+\r
+#define R_8237_DMA_CHMODE_CH0_3                   0x0b\r
+#define R_8237_DMA_CHMODE_CH4_7                   0xd6\r
+#define   V_8237_DMA_CHMODE_DEMAND                0x00\r
+#define   V_8237_DMA_CHMODE_SINGLE                0x40\r
+#define   V_8237_DMA_CHMODE_CASCADE               0xc0\r
+#define   B_8237_DMA_CHMODE_DECREMENT             0x20\r
+#define   B_8237_DMA_CHMODE_INCREMENT             0x00\r
+#define   B_8237_DMA_CHMODE_AE                    0x10\r
+#define   V_8237_DMA_CHMODE_VERIFY                0\r
+#define   V_8237_DMA_CHMODE_IO2MEM                0x04\r
+#define   V_8237_DMA_CHMODE_MEM2IO                0x08\r
+\r
+#define R_8237_DMA_CBPR_CH0_3                     0x0c\r
+#define R_8237_DMA_CBPR_CH4_7                     0xd8\r
+\r
+#define R_8237_DMA_MCR_CH0_3                      0x0d\r
+#define R_8237_DMA_MCR_CH4_7                      0xda\r
+\r
+#define R_8237_DMA_CLMSK_CH0_3                    0x0e\r
+#define R_8237_DMA_CLMSK_CH4_7                    0xdc\r
+\r
+#define R_8237_DMA_WRMSK_CH0_3                    0x0f\r
+#define R_8237_DMA_WRMSK_CH4_7                    0xde\r
+\r
+typedef enum {\r
+  IsaAccessTypeUnknown,\r
+  IsaAccessTypeIo,\r
+  IsaAccessTypeMem,\r
+  IsaAccessTypeMaxType\r
+} ISA_ACCESS_TYPE;\r
+\r
+typedef struct {\r
+  UINT8 Address;\r
+  UINT8 Page;\r
+  UINT8 Count;\r
+} EFI_ISA_DMA_REGISTERS;\r
+\r
+//\r
+// ISA I/O Device Structure\r
+//\r
+#define ISA_IO_DEVICE_SIGNATURE SIGNATURE_32 ('i', 's', 'a', 'i')\r
+\r
+typedef struct {\r
+  UINT32                                    Signature;\r
+  EFI_HANDLE                                Handle;\r
+  EFI_ISA_IO_PROTOCOL                       IsaIo;\r
+  EFI_PCI_IO_PROTOCOL                       *PciIo;\r
+} ISA_IO_DEVICE;\r
+\r
+#define ISA_IO_DEVICE_FROM_ISA_IO_THIS(a) CR (a, ISA_IO_DEVICE, IsaIo, ISA_IO_DEVICE_SIGNATURE)\r
+\r
+//\r
+// Mapping structure for performing ISA DMA to a buffer above 16 MB\r
+//\r
+typedef struct {\r
+  EFI_ISA_IO_PROTOCOL_OPERATION Operation;\r
+  UINTN                         NumberOfBytes;\r
+  UINTN                         NumberOfPages;\r
+  EFI_PHYSICAL_ADDRESS          HostAddress;\r
+  EFI_PHYSICAL_ADDRESS          MappedHostAddress;\r
+} ISA_MAP_INFO;\r
+\r
+//\r
+// EFI Driver Binding Protocol Interface Functions\r
+//\r
+\r
+/** \r
+  Tests to see if a controller can be managed by the ISA Driver.\r
+\r
+  How the Start() function of a driver is implemented can affect how the Supported() function is implemented.\r
+\r
+  @param[in] This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.  \r
+  @param[in] Controller           The handle of the controller to test.\r
+  @param[in] RemainingDevicePath  A pointer to the remaining portion of a device path.\r
+  \r
+  @retval EFI_SUCCESS             The device is supported by this driver.\r
+  @retval EFI_ALREADY_STARTED     The device is already being managed by this driver.\r
+  @retval EFI_ACCESS_DENIED       The device is already being managed by a different driver \r
+                                  or an application that requires exclusive access.\r
+  @retval EFI_UNSUPPORTED         The device is is not supported by this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  );\r
+\r
+/**\r
+  Start this driver on ControllerHandle. \r
+  \r
+  The Start() function is designed to be invoked from the EFI boot service ConnectController(). \r
+  As a result, much of the error checking on the parameters to Start() has been moved into this \r
+  common boot service. It is legal to call Start() from other locations, but the following calling \r
+  restrictions must be followed or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE.\r
+  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+     EFI_DEVICE_PATH_PROTOCOL.\r
+  3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.  \r
+\r
+  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle     The handle of the controller to start. This handle \r
+                                   must support a protocol interface that supplies \r
+                                   an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path. \r
+                                   This parameter is ignored by device drivers, and is optional for bus drivers.\r
+\r
+  @retval EFI_SUCCESS              The device was started.\r
+  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.\r
+                                   Currently not implemented.\r
+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.\r
+  @retval Others                   The driver failded to start the device.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  );\r
+\r
+/**\r
+  Stop this driver on ControllerHandle. \r
+  \r
+  The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). \r
+  As a result, much of the error checking on the parameters to Stop() has been moved \r
+  into this common boot service. It is legal to call Stop() from other locations, \r
+  but the following calling restrictions must be followed or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+     same driver's Start() function.\r
+  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+     EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+     Start() function, and the Start() function must have called OpenProtocol() on\r
+     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+  \r
+  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must \r
+                                support a bus specific I/O protocol for the driver \r
+                                to use to stop the device.\r
+  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.\r
+  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL \r
+                                if NumberOfChildren is 0.\r
+\r
+  @retval EFI_SUCCESS           The device was stopped.\r
+  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoDriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  * This,\r
+  IN  EFI_HANDLE                   Controller,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   * ChildHandleBuffer OPTIONAL\r
+  );\r
+\r
+//\r
+// Function Prototypes\r
+//\r
+\r
+/**\r
+  Initializes an ISA I/O Instance\r
+\r
+  @param[in] IsaIoDevice            The isa device to be initialized.\r
+  @param[in] DevicePath             The device path of the isa device.\r
+  @param[in] Resources              The ACPI resource list.\r
+  \r
+**/\r
+VOID\r
+InitializeIsaIoInstance (\r
+  IN ISA_IO_DEVICE               *IsaIoDevice,\r
+  IN EFI_DEVICE_PATH_PROTOCOL    *DevicePath,\r
+  IN ACPI_RESOURCE_HEADER_PTR    Resources\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.c b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.c
new file mode 100644 (file)
index 0000000..9058d78
--- /dev/null
@@ -0,0 +1,1796 @@
+/** @file\r
+  The implementation for EFI_ISA_IO_PROTOCOL. \r
+  \r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "IsaIo.h"\r
+\r
+//\r
+// Module Variables\r
+//\r
+EFI_ISA_IO_PROTOCOL mIsaIoInterface = {\r
+  {    \r
+    IsaIoMemRead,\r
+    IsaIoMemWrite\r
+  },\r
+  {   \r
+    IsaIoIoRead,\r
+    IsaIoIoWrite\r
+  },\r
+  IsaIoCopyMem,\r
+  IsaIoMap,\r
+  IsaIoUnmap,\r
+  IsaIoAllocateBuffer,\r
+  IsaIoFreeBuffer,\r
+  IsaIoFlush,\r
+  NULL,\r
+  0,\r
+  NULL\r
+};\r
+\r
+EFI_ISA_DMA_REGISTERS  mDmaRegisters[8] = {\r
+  {\r
+    0x00,\r
+    0x87,\r
+    0x01\r
+  },\r
+  {\r
+    0x02,\r
+    0x83,\r
+    0x03\r
+  },\r
+  {\r
+    0x04,\r
+    0x81,\r
+    0x05\r
+  },\r
+  {\r
+    0x06,\r
+    0x82,\r
+    0x07\r
+  },\r
+  {\r
+    0x00,\r
+    0x00,\r
+    0x00\r
+  },  // Channel 4 is invalid\r
+  {\r
+    0xC4,\r
+    0x8B,\r
+    0xC6\r
+  },\r
+  {\r
+    0xC8,\r
+    0x89,\r
+    0xCA\r
+  },\r
+  {\r
+    0xCC,\r
+    0x8A,\r
+    0xCE\r
+  },\r
+};\r
+\r
+/**\r
+  Verifies access to an ISA device\r
+\r
+  @param[in] IsaIoDevice         The ISA device to be verified.\r
+  @param[in] Type                The Access type. The input must be either IsaAccessTypeMem or IsaAccessTypeIo.\r
+  @param[in] Width               The width of the memory operation.\r
+  @param[in] Count               The number of memory operations to perform. \r
+  @param[in] Offset              The offset in ISA memory space to start the memory operation.  \r
+  \r
+  @retval EFI_SUCCESS            Verify success.\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED        The device ont support the access type.\r
+**/\r
+EFI_STATUS\r
+IsaIoVerifyAccess (\r
+  IN ISA_IO_DEVICE              *IsaIoDevice,\r
+  IN ISA_ACCESS_TYPE            Type,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINTN                      Count,\r
+  IN UINT32                     Offset\r
+  )\r
+{\r
+  EFI_ISA_ACPI_RESOURCE *Item;\r
+  EFI_STATUS            Status;\r
+\r
+  if (Width < EfiIsaIoWidthUint8 ||\r
+      Width >= EfiIsaIoWidthMaximum ||\r
+      Width == EfiIsaIoWidthReserved ||\r
+      Width == EfiIsaIoWidthFifoReserved ||\r
+      Width == EfiIsaIoWidthFillReserved\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // If Width is EfiIsaIoWidthFifoUintX then convert to EfiIsaIoWidthUintX\r
+  // If Width is EfiIsaIoWidthFillUintX then convert to EfiIsaIoWidthUintX\r
+  //\r
+  if (Width >= EfiIsaIoWidthFifoUint8 && Width < EfiIsaIoWidthFifoReserved) {\r
+    Count = 1;\r
+  }\r
+\r
+  Width = (EFI_ISA_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
+\r
+  Status  = EFI_UNSUPPORTED;\r
+  Item    = IsaIoDevice->IsaIo.ResourceList->ResourceItem;\r
+  while (Item->Type != EfiIsaAcpiResourceEndOfList) {\r
+    if ((Type == IsaAccessTypeMem && Item->Type == EfiIsaAcpiResourceMemory) ||\r
+        (Type == IsaAccessTypeIo && Item->Type == EfiIsaAcpiResourceIo)) {\r
+      if (Offset >= Item->StartRange && (Offset + Count * (UINT32)(1 << Width)) - 1 <= Item->EndRange) {\r
+        return EFI_SUCCESS;\r
+      }\r
+\r
+      if (Offset >= Item->StartRange && Offset <= Item->EndRange) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+\r
+    Item++;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Convert the IO Information in ACPI descriptor to IO ISA Attribute.\r
+\r
+  @param[in] Information   The IO Information in ACPI descriptor\r
+\r
+  @return UINT32           The IO ISA Attribute\r
+**/\r
+UINT32\r
+IsaIoAttribute (\r
+  IN UINT8                            Information\r
+  )\r
+{\r
+  UINT32             Attribute;\r
+\r
+  Attribute = 0;\r
+\r
+  switch (Information & EFI_ACPI_IO_DECODE_MASK) {\r
+    case EFI_ACPI_IO_DECODE_16_BIT:\r
+      Attribute |= EFI_ISA_ACPI_IO_DECODE_16_BITS;\r
+      break;\r
+      \r
+    case EFI_ACPI_IO_DECODE_10_BIT:\r
+      Attribute |= EFI_ISA_ACPI_IO_DECODE_10_BITS;\r
+      break;\r
+  }\r
+\r
+  return Attribute;\r
+}\r
+\r
+/**\r
+  Convert the IRQ Information in ACPI descriptor to IRQ ISA Attribute.\r
+\r
+  @param[in] Information   The IRQ Information in ACPI descriptor\r
+\r
+  @return UINT32           The IRQ ISA Attribute\r
+**/\r
+UINT32\r
+IsaIrqAttribute (\r
+  IN UINT8                            Information\r
+  )\r
+{\r
+  UINT32             Attribute;\r
+\r
+  Attribute = 0;\r
+\r
+  if ((Information & EFI_ACPI_IRQ_POLARITY_MASK) == EFI_ACPI_IRQ_HIGH_TRUE) {\r
+    if ((Information & EFI_ACPI_IRQ_MODE) == EFI_ACPI_IRQ_LEVEL_TRIGGERED) {\r
+      Attribute = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE;\r
+    } else {\r
+      Attribute = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE;\r
+    }\r
+  } else {\r
+    if ((Information & EFI_ACPI_IRQ_MODE) == EFI_ACPI_IRQ_LEVEL_TRIGGERED) {\r
+      Attribute = EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE;\r
+    } else {\r
+      Attribute = EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE;\r
+    }\r
+  }\r
+  return Attribute;\r
+}\r
+\r
+/**\r
+  Convert the Memory Information in ACPI descriptor to Memory ISA Attribute.\r
+\r
+  @param[in] Information   The Memory Information in ACPI descriptor\r
+\r
+  @return UINT32           The Memory ISA Attribute\r
+**/\r
+UINT32\r
+IsaMemoryAttribute (\r
+  IN UINT8                            Information\r
+  )\r
+{\r
+  UINT32             Attribute;\r
+\r
+  Attribute = 0;\r
+\r
+  switch (Information & EFI_ACPI_MEMORY_WRITE_STATUS_MASK) {\r
+    case EFI_ACPI_MEMORY_WRITABLE:\r
+      Attribute |= EFI_ISA_ACPI_MEMORY_WRITEABLE;\r
+      break;\r
+  }\r
+\r
+  return Attribute;\r
+}\r
+\r
+/**\r
+  Convert the DMA Information in ACPI descriptor to DMA ISA Attribute.\r
+\r
+  @param[in] Information   The DMA Information in ACPI descriptor\r
+\r
+  @return UINT32           The DMA ISA Attribute\r
+**/\r
+UINT32\r
+IsaDmaAttribute (\r
+  IN UINT8                            Information\r
+  )\r
+{\r
+  UINT32             Attribute;\r
+\r
+  Attribute = EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE;\r
+  \r
+  switch (Information & EFI_ACPI_DMA_SPEED_TYPE_MASK) {\r
+    case EFI_ACPI_DMA_SPEED_TYPE_COMPATIBILITY:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE;\r
+      break;\r
+    case EFI_ACPI_DMA_SPEED_TYPE_A:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A;\r
+      break;\r
+    case EFI_ACPI_DMA_SPEED_TYPE_B:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B;\r
+      break;\r
+    case EFI_ACPI_DMA_SPEED_TYPE_F:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C;\r
+      break;\r
+  }\r
+\r
+  switch (Information & EFI_ACPI_DMA_TRANSFER_TYPE_MASK) {\r
+    case EFI_ACPI_DMA_TRANSFER_TYPE_8_BIT:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8;\r
+      break;\r
+    case EFI_ACPI_DMA_TRANSFER_TYPE_16_BIT:\r
+      Attribute |= EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16;\r
+      break;\r
+  }\r
+\r
+  return Attribute;\r
+}\r
+\r
+/**\r
+  Convert the ACPI resource descriptor to ISA resource descriptor.\r
+\r
+  @param[in]  AcpiResource          Pointer to the ACPI resource descriptor\r
+  @param[out] IsaResource           The optional pointer to the buffer to\r
+                                    store the converted ISA resource descriptor\r
+\r
+  @return     UINTN                 Number of ISA resource descriptor needed\r
+**/\r
+UINTN\r
+AcpiResourceToIsaResource (\r
+  IN  ACPI_RESOURCE_HEADER_PTR        AcpiResource,\r
+  OUT EFI_ISA_ACPI_RESOURCE           *IsaResource   OPTIONAL\r
+  )\r
+{\r
+  UINT32                                        Index;\r
+  UINTN                                         Count;\r
+  UINT32                                        LastIndex;\r
+  EFI_ACPI_IO_PORT_DESCRIPTOR                   *Io;\r
+  EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR    *FixedIo;\r
+  EFI_ACPI_IRQ_DESCRIPTOR                       *Irq;\r
+  EFI_ACPI_DMA_DESCRIPTOR                       *Dma;\r
+  EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR       *Memory;\r
+  EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR *FixedMemory;\r
+\r
+  Count     = 0;\r
+  LastIndex = 0;\r
+\r
+  switch (AcpiResource.SmallHeader->Byte) {\r
+    case ACPI_DMA_DESCRIPTOR:\r
+      Dma = (EFI_ACPI_DMA_DESCRIPTOR *) AcpiResource.SmallHeader;\r
+      for (Index = 0; Index < sizeof (Dma->ChannelMask) * 8; Index++) {\r
+        if (Dma->ChannelMask & (1 << Index)) {\r
+          if ((Count > 0) && (LastIndex + 1 == Index)) {\r
+            if (IsaResource != NULL) {\r
+              IsaResource[Count - 1].EndRange ++;\r
+            }\r
+          } else {\r
+            if (IsaResource != NULL) {\r
+              IsaResource[Count].Type       = EfiIsaAcpiResourceDma;\r
+              IsaResource[Count].Attribute  = IsaDmaAttribute (Dma->Information);\r
+              IsaResource[Count].StartRange = Index;\r
+              IsaResource[Count].EndRange   = Index;\r
+            }\r
+            Count ++;\r
+          }\r
+\r
+          LastIndex = Index;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case ACPI_IO_PORT_DESCRIPTOR:\r
+      Io = (EFI_ACPI_IO_PORT_DESCRIPTOR *) AcpiResource.SmallHeader;\r
+      if (IsaResource != NULL) {\r
+        IsaResource[Count].Type       = EfiIsaAcpiResourceIo;\r
+        IsaResource[Count].Attribute  = IsaIoAttribute (Io->Information);\r
+        IsaResource[Count].StartRange = Io->BaseAddressMin;\r
+        IsaResource[Count].EndRange   = Io->BaseAddressMin + Io->Length - 1;\r
+      }\r
+      Count ++;\r
+      break;\r
+\r
+    case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR:\r
+      FixedIo = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) AcpiResource.SmallHeader;\r
+      if (IsaResource != NULL) {\r
+        IsaResource[Count].Type       = EfiIsaAcpiResourceIo;\r
+        IsaResource[Count].Attribute  = EFI_ISA_ACPI_IO_DECODE_10_BITS;\r
+        IsaResource[Count].StartRange = FixedIo->BaseAddress;\r
+        IsaResource[Count].EndRange   = FixedIo->BaseAddress + FixedIo->Length - 1;\r
+      }\r
+      Count ++;\r
+      break;\r
+\r
+    case ACPI_IRQ_DESCRIPTOR:\r
+    case ACPI_IRQ_NOFLAG_DESCRIPTOR:\r
+      Irq = (EFI_ACPI_IRQ_DESCRIPTOR *) AcpiResource.SmallHeader;\r
+      for (Index = 0; Index < sizeof (Irq->Mask) * 8; Index++) {\r
+        if (Irq->Mask & (1 << Index)) {\r
+          if ((Count > 0) && (LastIndex + 1 == Index)) {\r
+            if (IsaResource != NULL) {\r
+              IsaResource[Count - 1].EndRange ++;\r
+            }\r
+          } else {\r
+            if (IsaResource != NULL) {\r
+              IsaResource[Count].Type       = EfiIsaAcpiResourceInterrupt;\r
+              if (AcpiResource.SmallHeader->Byte == ACPI_IRQ_DESCRIPTOR) {\r
+                IsaResource[Count].Attribute = IsaIrqAttribute (Irq->Information);\r
+              } else {\r
+                IsaResource[Count].Attribute  = EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE;\r
+              }\r
+              IsaResource[Count].StartRange = Index;\r
+              IsaResource[Count].EndRange   = Index;\r
+            }\r
+            Count++;\r
+          }\r
+\r
+          LastIndex = Index;\r
+        }\r
+      }\r
+      break;\r
+\r
+    case ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR:\r
+      Memory = (EFI_ACPI_32_BIT_MEMORY_RANGE_DESCRIPTOR *) AcpiResource.LargeHeader;\r
+      if (IsaResource != NULL) {\r
+        IsaResource[Count].Type       = EfiIsaAcpiResourceMemory;\r
+        IsaResource[Count].Attribute  = IsaMemoryAttribute (Memory->Information);\r
+        IsaResource[Count].StartRange = Memory->BaseAddressMin;\r
+        IsaResource[Count].EndRange   = Memory->BaseAddressMin + Memory->Length - 1;\r
+      }\r
+      Count ++;\r
+      break;\r
+\r
+    case ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR:\r
+      FixedMemory = (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR *) AcpiResource.LargeHeader;\r
+      if (IsaResource != NULL) {\r
+        IsaResource[Count].Type       = EfiIsaAcpiResourceMemory;\r
+        IsaResource[Count].Attribute  = IsaMemoryAttribute (FixedMemory->Information);\r
+        IsaResource[Count].StartRange = FixedMemory->BaseAddress;\r
+        IsaResource[Count].EndRange   = FixedMemory->BaseAddress + FixedMemory->Length - 1;\r
+      }\r
+      Count ++;\r
+      break;\r
+\r
+    case ACPI_END_TAG_DESCRIPTOR:\r
+      if (IsaResource != NULL) {\r
+        IsaResource[Count].Type       = EfiIsaAcpiResourceEndOfList;\r
+        IsaResource[Count].Attribute  = 0;\r
+        IsaResource[Count].StartRange = 0;\r
+        IsaResource[Count].EndRange   = 0;\r
+      }\r
+      Count ++;\r
+      break;\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
+/**\r
+  Initializes an ISA I/O Instance\r
+\r
+  @param[in] IsaIoDevice            The isa device to be initialized.\r
+  @param[in] DevicePath             The device path of the isa device.\r
+  @param[in] Resources              The ACPI resource list.\r
+  \r
+**/\r
+VOID\r
+InitializeIsaIoInstance (\r
+  IN ISA_IO_DEVICE               *IsaIoDevice,\r
+  IN EFI_DEVICE_PATH_PROTOCOL    *DevicePath,\r
+  IN ACPI_RESOURCE_HEADER_PTR    Resources\r
+  )\r
+{\r
+  UINTN                                       Index;\r
+  ACPI_HID_DEVICE_PATH                        *AcpiNode;\r
+  ACPI_RESOURCE_HEADER_PTR                    ResourcePtr;\r
+\r
+  //\r
+  // Use the ISA IO Protocol structure template to initialize the ISA IO instance\r
+  //\r
+  CopyMem (\r
+    &IsaIoDevice->IsaIo,\r
+    &mIsaIoInterface,\r
+    sizeof (EFI_ISA_IO_PROTOCOL)\r
+    );\r
+\r
+  //\r
+  // Count the resources including the ACPI End Tag\r
+  //\r
+  ResourcePtr = Resources;\r
+  Index       = 0;\r
+  while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {\r
+    \r
+    Index += AcpiResourceToIsaResource (ResourcePtr, NULL);\r
+\r
+    if (ResourcePtr.SmallHeader->Bits.Type == 0) {\r
+      ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader\r
+                              + ResourcePtr.SmallHeader->Bits.Length\r
+                              + sizeof (*ResourcePtr.SmallHeader));\r
+    } else {\r
+      ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader\r
+                              + ResourcePtr.LargeHeader->Length\r
+                              + sizeof (*ResourcePtr.LargeHeader));\r
+    }\r
+\r
+  }\r
+  //\r
+  // Get the Isa Resource count for ACPI End Tag\r
+  //\r
+  Index += AcpiResourceToIsaResource (ResourcePtr, NULL);\r
+\r
+  //\r
+  // Initialize the ResourceList\r
+  //\r
+  IsaIoDevice->IsaIo.ResourceList = AllocatePool (sizeof (EFI_ISA_ACPI_RESOURCE_LIST) + Index * sizeof (EFI_ISA_ACPI_RESOURCE));\r
+  ASSERT (IsaIoDevice->IsaIo.ResourceList != NULL);\r
+  IsaIoDevice->IsaIo.ResourceList->ResourceItem = (EFI_ISA_ACPI_RESOURCE *) (IsaIoDevice->IsaIo.ResourceList + 1);\r
+\r
+  AcpiNode = (ACPI_HID_DEVICE_PATH *) ((UINT8 *) DevicePath + GetDevicePathSize (DevicePath) - END_DEVICE_PATH_LENGTH - sizeof (ACPI_HID_DEVICE_PATH));\r
+  IsaIoDevice->IsaIo.ResourceList->Device.HID = AcpiNode->HID;\r
+  IsaIoDevice->IsaIo.ResourceList->Device.UID = AcpiNode->UID;\r
+\r
+  ResourcePtr = Resources;\r
+  Index       = 0;\r
+  while (ResourcePtr.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {\r
+\r
+    Index += AcpiResourceToIsaResource (ResourcePtr, &IsaIoDevice->IsaIo.ResourceList->ResourceItem[Index]);\r
+\r
+    if (ResourcePtr.SmallHeader->Bits.Type == 0) {\r
+      ResourcePtr.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.SmallHeader\r
+                              + ResourcePtr.SmallHeader->Bits.Length\r
+                              + sizeof (*ResourcePtr.SmallHeader));\r
+    } else {\r
+      ResourcePtr.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) ResourcePtr.LargeHeader\r
+                              + ResourcePtr.LargeHeader->Length\r
+                              + sizeof (*ResourcePtr.LargeHeader));\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Convert the ACPI End Tag\r
+  //\r
+  AcpiResourceToIsaResource (ResourcePtr, &IsaIoDevice->IsaIo.ResourceList->ResourceItem[Index]);\r
+}\r
+\r
+/**\r
+  Performs an ISA I/O Read Cycle\r
+\r
+  @param[in]  This              A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width             Specifies the width of the I/O operation.\r
+  @param[in]  Offset            The offset in ISA I/O space to start the I/O operation.  \r
+  @param[in]  Count             The number of I/O operations to perform. \r
+  @param[out] Buffer            The destination buffer to store the results\r
+\r
+  @retval EFI_SUCCESS           The data was read from the device sucessfully.\r
+  @retval EFI_UNSUPPORTED       The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoIoRead (\r
+  IN  EFI_ISA_IO_PROTOCOL        *This,\r
+  IN  EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT32                     Offset,\r
+  IN  UINTN                      Count,\r
+  OUT VOID                       *Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  //\r
+  // Verify Isa IO Access\r
+  //\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeIo,\r
+             Width,\r
+             Count,\r
+             Offset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoDevice->PciIo->Io.Read (\r
+                                    IsaIoDevice->PciIo,\r
+                                    (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                                    EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                    Offset,\r
+                                    Count,\r
+                                    Buffer\r
+                                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Performs an ISA I/O Write Cycle\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Width               Specifies the width of the I/O operation.\r
+  @param[in] Offset              The offset in ISA I/O space to start the I/O operation.  \r
+  @param[in] Count               The number of I/O operations to perform. \r
+  @param[in] Buffer              The source buffer to write data from\r
+\r
+  @retval EFI_SUCCESS            The data was writen to the device sucessfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoIoWrite (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     Offset,\r
+  IN UINTN                      Count,\r
+  IN VOID                       *Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  //\r
+  // Verify Isa IO Access\r
+  //\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeIo,\r
+             Width,\r
+             Count,\r
+             Offset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoDevice->PciIo->Io.Write (\r
+                                    IsaIoDevice->PciIo,\r
+                                    (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                                    EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                    Offset,\r
+                                    Count,\r
+                                    Buffer\r
+                                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Writes an 8-bit I/O Port\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Offset              The offset in ISA IO space to start the IO operation.  \r
+  @param[in] Value               The data to write port.\r
+\r
+  @retval EFI_SUCCESS            Success.\r
+  @retval EFI_INVALID_PARAMETER  Parameter is invalid.\r
+  @retval EFI_UNSUPPORTED        The address range specified by Offset is not valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+WritePort (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINT32               Offset,\r
+  IN UINT8                Value\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  Status = IsaIoDevice->PciIo->Io.Write (\r
+                                    IsaIoDevice->PciIo,\r
+                                    EfiPciIoWidthUint8,\r
+                                    EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                    Offset,\r
+                                    1,\r
+                                    &Value\r
+                                    );\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Wait for 50 microseconds to take affect.\r
+  //\r
+  gBS->Stall (50);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Writes I/O operation base address and count number to a 8 bit I/O Port.\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] AddrOffset          The address' offset.\r
+  @param[in] PageOffset          The page's offest.\r
+  @param[in] CountOffset         The count's offset.\r
+  @param[in] BaseAddress         The base address.\r
+  @param[in] Count               The number of I/O operations to perform. \r
+  \r
+  @retval EFI_SUCCESS            Success.\r
+  @retval EFI_INVALID_PARAMETER  Parameter is invalid.\r
+  @retval EFI_UNSUPPORTED        The address range specified by these Offsets and Count is not valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+WriteDmaPort (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINT32               AddrOffset,\r
+  IN UINT32               PageOffset,\r
+  IN UINT32               CountOffset,\r
+  IN UINT32               BaseAddress,\r
+  IN UINT16               Count\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = WritePort (This, AddrOffset, (UINT8) (BaseAddress & 0xff));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, AddrOffset, (UINT8) ((BaseAddress >> 8) & 0xff));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, PageOffset, (UINT8) ((BaseAddress >> 16) & 0xff));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, CountOffset, (UINT8) (Count & 0xff));\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, CountOffset, (UINT8) ((Count >> 8) & 0xff));\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Unmaps a memory region for DMA\r
+\r
+  @param[in] This           A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Mapping        The mapping value returned from EFI_ISA_IO.Map().\r
+\r
+  @retval EFI_SUCCESS       The range was unmapped.\r
+  @retval EFI_DEVICE_ERROR  The data was not committed to the target system memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoUnmap (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN VOID                 *Mapping\r
+  )\r
+{\r
+  ISA_MAP_INFO  *IsaMapInfo;\r
+\r
+  //\r
+  // Check if DMA is supported.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // See if the Map() operation associated with this Unmap() required a mapping\r
+  // buffer.If a mapping buffer was not required, then this function simply\r
+  // returns EFI_SUCCESS.\r
+  //\r
+  if (Mapping != NULL) {\r
+    //\r
+    // Get the MAP_INFO structure from Mapping\r
+    //\r
+    IsaMapInfo = (ISA_MAP_INFO *) Mapping;\r
+\r
+    //\r
+    // If this is a write operation from the Agent's point of view,\r
+    // then copy the contents of the mapped buffer into the real buffer\r
+    // so the processor can read the contents of the real buffer.\r
+    //\r
+    if (IsaMapInfo->Operation == EfiIsaIoOperationBusMasterWrite) {\r
+      CopyMem (\r
+        (VOID *) (UINTN) IsaMapInfo->HostAddress,\r
+        (VOID *) (UINTN) IsaMapInfo->MappedHostAddress,\r
+        IsaMapInfo->NumberOfBytes\r
+        );\r
+    }\r
+    //\r
+    // Free the mapped buffer and the MAP_INFO structure.\r
+    //\r
+    gBS->FreePages (IsaMapInfo->MappedHostAddress, IsaMapInfo->NumberOfPages);\r
+    FreePool (IsaMapInfo);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Flushes any posted write data to the system memory.\r
+\r
+  @param[in] This             A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+\r
+  @retval  EFI_SUCCESS        The buffers were flushed.\r
+  @retval  EFI_DEVICE_ERROR   The buffers were not flushed due to a hardware error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoFlush (\r
+  IN EFI_ISA_IO_PROTOCOL  *This\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  Status = IsaIoDevice->PciIo->Flush (IsaIoDevice->PciIo);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Performs an ISA Memory Read Cycle\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width              Specifies the width of the memory operation.\r
+  @param[in]  Offset             The offset in ISA memory space to start the memory operation.  \r
+  @param[in]  Count              The number of memory operations to perform. \r
+  @param[out] Buffer             The destination buffer to store the results\r
\r
+  @retval EFI_SUCCESS            The data was read from the device successfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMemRead (\r
+  IN  EFI_ISA_IO_PROTOCOL        *This,\r
+  IN  EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT32                     Offset,\r
+  IN  UINTN                      Count,\r
+  OUT VOID                       *Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  //\r
+  // Check if ISA memory is supported.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  //\r
+  // Verify the Isa Io Access\r
+  //\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeMem,\r
+             Width,\r
+             Count,\r
+             Offset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoDevice->PciIo->Mem.Read (\r
+                                     IsaIoDevice->PciIo,\r
+                                     (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                                     EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                     Offset,\r
+                                     Count,\r
+                                     Buffer\r
+                                     );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Performs an ISA Memory Write Cycle\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.  \r
+  @param[in] Width               Specifies the width of the memory operation.\r
+  @param[in] Offset              The offset in ISA memory space to start the memory operation.  \r
+  @param[in] Count               The number of memory operations to perform. \r
+  @param[in] Buffer              The source buffer to write data from\r
+\r
+  @retval EFI_SUCCESS            The data was written to the device sucessfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMemWrite (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     Offset,\r
+  IN UINTN                      Count,\r
+  IN VOID                       *Buffer\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  //\r
+  // Check if ISA memory is supported.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  //\r
+  // Verify Isa IO Access\r
+  //\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeMem,\r
+             Width,\r
+             Count,\r
+             Offset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoDevice->PciIo->Mem.Write (\r
+                                     IsaIoDevice->PciIo,\r
+                                     (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                                     EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                     Offset,\r
+                                     Count,\r
+                                     Buffer\r
+                                     );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Copy one region of ISA memory space to another region of ISA memory space on the ISA controller.\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width              Specifies the width of the memory copy operation.\r
+  @param[in]  DestOffset         The offset of the destination \r
+  @param[in]  SrcOffset          The offset of the source\r
+  @param[in]  Count              The number of memory copy  operations to perform\r
+\r
+  @retval EFI_SUCCESS            The data was copied sucessfully.\r
+  @retval EFI_UNSUPPORTED        The DestOffset or SrcOffset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoCopyMem (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     DestOffset,\r
+  IN UINT32                     SrcOffset,\r
+  IN UINTN                      Count\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  ISA_IO_DEVICE *IsaIoDevice;\r
+\r
+  //\r
+  // Check if ISA memory is supported.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_ISA_MEMORY) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);\r
+\r
+  //\r
+  // Verify Isa IO Access for destination and source\r
+  //\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeMem,\r
+             Width,\r
+             Count,\r
+             DestOffset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoVerifyAccess (\r
+             IsaIoDevice,\r
+             IsaAccessTypeMem,\r
+             Width,\r
+             Count,\r
+             SrcOffset\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = IsaIoDevice->PciIo->CopyMem (\r
+                                 IsaIoDevice->PciIo,\r
+                                 (EFI_PCI_IO_PROTOCOL_WIDTH) Width,\r
+                                 EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                 DestOffset,\r
+                                 EFI_PCI_IO_PASS_THROUGH_BAR,\r
+                                 SrcOffset,\r
+                                 Count\r
+                                 );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Maps a memory region for DMA, note this implementation\r
+  only supports slave read/write operation to save code size.\r
+\r
+  @param This                    A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param Operation               Indicates the type of DMA (slave or bus master), and if \r
+                                 the DMA operation is going to read or write to system memory. \r
+  @param ChannelNumber           The slave channel number to use for this DMA operation. \r
+                                 If Operation and ChannelAttributes shows that this device \r
+                                 performs bus mastering DMA, then this field is ignored.  \r
+                                 The legal range for this field is 0..7.  \r
+  @param ChannelAttributes       The attributes of the DMA channel to use for this DMA operation\r
+  @param HostAddress             The system memory address to map to the device.  \r
+  @param NumberOfBytes           On input the number of bytes to map.  On output the number \r
+                                 of bytes that were mapped.\r
+  @param DeviceAddress           The resulting map address for the bus master device to use \r
+                                 to access the hosts HostAddress.  \r
+  @param Mapping                 A resulting value to pass to EFI_ISA_IO.Unmap().\r
+\r
+  @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER  The Operation or HostAddress is undefined.\r
+  @retval EFI_UNSUPPORTED        The HostAddress can not be mapped as a common buffer.\r
+  @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+IsaIoMapOnlySupportSlaveReadWrite (\r
+  IN     EFI_ISA_IO_PROTOCOL            *This,\r
+  IN     EFI_ISA_IO_PROTOCOL_OPERATION  Operation,\r
+  IN     UINT8                          ChannelNumber  OPTIONAL,\r
+  IN     UINT32                         ChannelAttributes,\r
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
+  ISA_MAP_INFO          *IsaMapInfo;\r
+  UINT8                 DmaMode;\r
+  UINTN                 MaxNumberOfBytes;\r
+  UINT32                BaseAddress;\r
+  UINT16                Count;\r
+  UINT8                 DmaMask;\r
+  UINT8                 DmaClear;\r
+  UINT8                 DmaChannelMode;\r
+  \r
+  if ((NULL == This) ||\r
+      (NULL == HostAddress) ||\r
+      (NULL == NumberOfBytes) ||\r
+      (NULL == DeviceAddress) ||\r
+      (NULL == Mapping)\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Initialize the return values to their defaults\r
+  //\r
+  *Mapping = NULL;\r
+\r
+  //\r
+  // Make sure the Operation parameter is valid.\r
+  // Light IsaIo only supports two operations.\r
+  //\r
+  if (!(Operation == EfiIsaIoOperationSlaveRead || \r
+        Operation == EfiIsaIoOperationSlaveWrite)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (ChannelNumber >= 4) {\r
+    //\r
+    // The Light IsaIo doesn't support channelNumber larger than 4.\r
+    //\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Map the HostAddress to a DeviceAddress.\r
+  //\r
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
+  if ((PhysicalAddress + *NumberOfBytes) > BASE_16MB) {\r
+    //\r
+    // Common Buffer operations can not be remapped.  If the common buffer\r
+    // is above 16MB, then it is not possible to generate a mapping, so return\r
+    // an error.\r
+    //\r
+    if (Operation == EfiIsaIoOperationBusMasterCommonBuffer) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Allocate an ISA_MAP_INFO structure to remember the mapping when Unmap()\r
+    // is called later.\r
+    //\r
+    IsaMapInfo = AllocatePool (sizeof (ISA_MAP_INFO));\r
+    if (IsaMapInfo == NULL) {\r
+      *NumberOfBytes = 0;\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Return a pointer to the MAP_INFO structure in Mapping\r
+    //\r
+    *Mapping = IsaMapInfo;\r
+\r
+    //\r
+    // Initialize the MAP_INFO structure\r
+    //\r
+    IsaMapInfo->Operation         = Operation;\r
+    IsaMapInfo->NumberOfBytes     = *NumberOfBytes;\r
+    IsaMapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES (*NumberOfBytes);\r
+    IsaMapInfo->HostAddress       = PhysicalAddress;\r
+    IsaMapInfo->MappedHostAddress = BASE_16MB - 1;\r
+\r
+    //\r
+    // Allocate a buffer below 16MB to map the transfer to.\r
+    //\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiBootServicesData,\r
+                    IsaMapInfo->NumberOfPages,\r
+                    &IsaMapInfo->MappedHostAddress\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (IsaMapInfo);\r
+      *NumberOfBytes  = 0;\r
+      *Mapping        = NULL;\r
+      return Status;\r
+    }\r
+    //\r
+    // If this is a read operation from the DMA agents's point of view,\r
+    // then copy the contents of the real buffer into the mapped buffer\r
+    // so the DMA agent can read the contents of the real buffer.\r
+    //\r
+    if (Operation == EfiIsaIoOperationSlaveRead) {\r
+      CopyMem (\r
+        (VOID *) (UINTN) IsaMapInfo->MappedHostAddress,\r
+        (VOID *) (UINTN) IsaMapInfo->HostAddress,\r
+        IsaMapInfo->NumberOfBytes\r
+        );\r
+    }\r
+    //\r
+    // The DeviceAddress is the address of the maped buffer below 16 MB\r
+    //\r
+    *DeviceAddress = IsaMapInfo->MappedHostAddress;\r
+  } else {\r
+    //\r
+    // The transfer is below 16 MB, so the DeviceAddress is simply the\r
+    // HostAddress\r
+    //\r
+    *DeviceAddress = PhysicalAddress;\r
+  }\r
+  \r
+  //\r
+  // Figure out what to program into the DMA Channel Mode Register\r
+  //\r
+  DmaMode = (UINT8) (B_8237_DMA_CHMODE_INCREMENT | (ChannelNumber & 0x03));\r
+  if (Operation == EfiIsaIoOperationSlaveRead) {\r
+    DmaMode |= V_8237_DMA_CHMODE_MEM2IO;\r
+  } else {\r
+    DmaMode |= V_8237_DMA_CHMODE_IO2MEM;\r
+  }\r
+  //\r
+  // We only support EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE in simplified IsaIo\r
+  //\r
+  DmaMode |= V_8237_DMA_CHMODE_SINGLE;\r
+\r
+  //\r
+  // A Slave DMA transfer can not cross a 64K boundary.\r
+  // Compute *NumberOfBytes based on this restriction.\r
+  //\r
+  MaxNumberOfBytes = 0x10000 - ((UINT32) (*DeviceAddress) & 0xffff);\r
+  if (*NumberOfBytes > MaxNumberOfBytes) {\r
+    *NumberOfBytes = MaxNumberOfBytes;\r
+  }\r
+  //\r
+  // Compute the values to program into the BaseAddress and Count registers\r
+  // of the Slave DMA controller\r
+  //\r
+  BaseAddress = (UINT32) (*DeviceAddress);\r
+  Count       = (UINT16) (*NumberOfBytes - 1);\r
+  //\r
+  // Program the DMA Write Single Mask Register for ChannelNumber\r
+  // Clear the DMA Byte Pointer Register\r
+  //\r
+  DmaMask         = R_8237_DMA_WRSMSK_CH0_3;\r
+  DmaClear        = R_8237_DMA_CBPR_CH0_3;\r
+  DmaChannelMode  = R_8237_DMA_CHMODE_CH0_3;\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaMask,\r
+             (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03))\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaClear,\r
+             (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03))\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, DmaChannelMode, DmaMode);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WriteDmaPort (\r
+             This,\r
+             mDmaRegisters[ChannelNumber].Address,\r
+             mDmaRegisters[ChannelNumber].Page,\r
+             mDmaRegisters[ChannelNumber].Count,\r
+             BaseAddress,\r
+             Count\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaMask,\r
+             (UINT8) (ChannelNumber & 0x03)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Maps a memory region for DMA. This implementation implement the \r
+  the full mapping support.\r
+\r
+  @param This                    A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param Operation               Indicates the type of DMA (slave or bus master), and if \r
+                                 the DMA operation is going to read or write to system memory. \r
+  @param ChannelNumber           The slave channel number to use for this DMA operation. \r
+                                 If Operation and ChannelAttributes shows that this device \r
+                                 performs bus mastering DMA, then this field is ignored.  \r
+                                 The legal range for this field is 0..7.  \r
+  @param ChannelAttributes       The attributes of the DMA channel to use for this DMA operation\r
+  @param HostAddress             The system memory address to map to the device.  \r
+  @param NumberOfBytes           On input the number of bytes to map.  On output the number \r
+                                 of bytes that were mapped.\r
+  @param DeviceAddress           The resulting map address for the bus master device to use \r
+                                 to access the hosts HostAddress.  \r
+  @param Mapping                 A resulting value to pass to EFI_ISA_IO.Unmap().\r
+\r
+  @retval EFI_SUCCESS           - The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.\r
+  @retval EFI_UNSUPPORTED       - The HostAddress can not be mapped as a common buffer.\r
+  @retval EFI_DEVICE_ERROR      - The system hardware could not map the requested address.\r
+  @retval EFI_OUT_OF_RESOURCES  - The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+IsaIoMapFullSupport (\r
+  IN     EFI_ISA_IO_PROTOCOL                                  *This,\r
+  IN     EFI_ISA_IO_PROTOCOL_OPERATION                        Operation,\r
+  IN     UINT8                                                ChannelNumber         OPTIONAL,\r
+  IN     UINT32                                               ChannelAttributes,\r
+  IN     VOID                                                 *HostAddress,\r
+  IN OUT UINTN                                                *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS                                 *DeviceAddress,\r
+  OUT    VOID                                                 **Mapping\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  BOOLEAN               Master;\r
+  BOOLEAN               Read;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
+  ISA_MAP_INFO          *IsaMapInfo;\r
+  UINT8                 DmaMode;\r
+  UINTN                 MaxNumberOfBytes;\r
+  UINT32                BaseAddress;\r
+  UINT16                Count;\r
+  UINT8                 DmaMask;\r
+  UINT8                 DmaClear;\r
+  UINT8                 DmaChannelMode;\r
+\r
+  if ((NULL == This) ||\r
+      (NULL == HostAddress) ||\r
+      (NULL == NumberOfBytes) ||\r
+      (NULL == DeviceAddress) ||\r
+      (NULL == Mapping)\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Initialize the return values to their defaults\r
+  //\r
+  *Mapping = NULL;\r
+\r
+  //\r
+  // Make sure the Operation parameter is valid\r
+  //\r
+  if (Operation < 0 || Operation >= EfiIsaIoOperationMaximum) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (ChannelNumber >= 8) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // See if this is a Slave DMA Operation\r
+  //\r
+  Master  = TRUE;\r
+  Read    = FALSE;\r
+  if (Operation == EfiIsaIoOperationSlaveRead) {\r
+    Operation = EfiIsaIoOperationBusMasterRead;\r
+    Master    = FALSE;\r
+    Read      = TRUE;\r
+  }\r
+\r
+  if (Operation == EfiIsaIoOperationSlaveWrite) {\r
+    Operation = EfiIsaIoOperationBusMasterWrite;\r
+    Master    = FALSE;\r
+    Read      = FALSE;\r
+  }\r
+\r
+  if (!Master) {\r
+    //\r
+    // Make sure that ChannelNumber is a valid channel number\r
+    // Channel 4 is used to cascade, so it is illegal.\r
+    //\r
+    if (ChannelNumber == 4 || ChannelNumber > 7) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    //\r
+    // This implementation only support COMPATIBLE DMA Transfers\r
+    //\r
+    if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE) == 0) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((ChannelAttributes &\r
+         (EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A |\r
+          EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B |\r
+          EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C)) != 0) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (ChannelNumber < 4) {\r
+      //\r
+      // If this is Channel 0..3, then the width must be 8 bit\r
+      //\r
+      if (((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8) == 0) ||\r
+          ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16) != 0)\r
+          ) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else {\r
+      //\r
+      // If this is Channel 4..7, then the width must be 16 bit\r
+      //\r
+      if (((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8) != 0) ||\r
+          ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16) == 0)) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+    //\r
+    // Either Demand Mode or Single Mode must be selected, but not both\r
+    //\r
+    if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE) != 0) {\r
+      if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) != 0) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    } else {\r
+      if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) == 0) {\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+    }\r
+  }\r
+  //\r
+  // Map the HostAddress to a DeviceAddress.\r
+  //\r
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;\r
+  if ((PhysicalAddress +*NumberOfBytes) > BASE_16MB) {\r
+    //\r
+    // Common Buffer operations can not be remapped.  If the common buffer\r
+    // is above 16MB, then it is not possible to generate a mapping, so return\r
+    // an error.\r
+    //\r
+    if (Operation == EfiIsaIoOperationBusMasterCommonBuffer) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Allocate an ISA_MAP_INFO structure to remember the mapping when Unmap()\r
+    // is called later.\r
+    //\r
+    IsaMapInfo = AllocatePool (sizeof (ISA_MAP_INFO));\r
+    if (IsaMapInfo == NULL) {\r
+      *NumberOfBytes = 0;\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    //\r
+    // Return a pointer to the MAP_INFO structure in Mapping\r
+    //\r
+    *Mapping = IsaMapInfo;\r
+\r
+    //\r
+    // Initialize the MAP_INFO structure\r
+    //\r
+    IsaMapInfo->Operation         = Operation;\r
+    IsaMapInfo->NumberOfBytes     = *NumberOfBytes;\r
+    IsaMapInfo->NumberOfPages     = EFI_SIZE_TO_PAGES (*NumberOfBytes);\r
+    IsaMapInfo->HostAddress       = PhysicalAddress;\r
+    IsaMapInfo->MappedHostAddress = BASE_16MB - 1;\r
+\r
+    //\r
+    // Allocate a buffer below 16MB to map the transfer to.\r
+    //\r
+    Status = gBS->AllocatePages (\r
+                    AllocateMaxAddress,\r
+                    EfiBootServicesData,\r
+                    IsaMapInfo->NumberOfPages,\r
+                    &IsaMapInfo->MappedHostAddress\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (IsaMapInfo);\r
+      *NumberOfBytes  = 0;\r
+      *Mapping        = NULL;\r
+      return Status;\r
+    }\r
+    //\r
+    // If this is a read operation from the DMA agents's point of view,\r
+    // then copy the contents of the real buffer into the mapped buffer\r
+    // so the DMA agent can read the contents of the real buffer.\r
+    //\r
+    if (Operation == EfiIsaIoOperationBusMasterRead) {\r
+      CopyMem (\r
+        (VOID *) (UINTN) IsaMapInfo->MappedHostAddress,\r
+        (VOID *) (UINTN) IsaMapInfo->HostAddress,\r
+        IsaMapInfo->NumberOfBytes\r
+        );\r
+    }\r
+    //\r
+    // The DeviceAddress is the address of the maped buffer below 16 MB\r
+    //\r
+    *DeviceAddress = IsaMapInfo->MappedHostAddress;\r
+  } else {\r
+    //\r
+    // The transfer is below 16 MB, so the DeviceAddress is simply the\r
+    // HostAddress\r
+    //\r
+    *DeviceAddress = PhysicalAddress;\r
+  }\r
+  //\r
+  // If this is a Bus Master operation then return\r
+  //\r
+  if (Master) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // Figure out what to program into the DMA Channel Mode Register\r
+  //\r
+  DmaMode = (UINT8) (B_8237_DMA_CHMODE_INCREMENT | (ChannelNumber & 0x03));\r
+  if (Read) {\r
+    DmaMode |= V_8237_DMA_CHMODE_MEM2IO;\r
+  } else {\r
+    DmaMode |= V_8237_DMA_CHMODE_IO2MEM;\r
+  }\r
+\r
+  if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE) != 0) {\r
+    DmaMode |= B_8237_DMA_CHMODE_AE;\r
+  }\r
+\r
+  if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) != 0) {\r
+    DmaMode |= V_8237_DMA_CHMODE_DEMAND;\r
+  }\r
+\r
+  if ((ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE) != 0) {\r
+    DmaMode |= V_8237_DMA_CHMODE_SINGLE;\r
+  }\r
+  //\r
+  // A Slave DMA transfer can not cross a 64K boundary.\r
+  // Compute *NumberOfBytes based on this restriction.\r
+  //\r
+  MaxNumberOfBytes = 0x10000 - ((UINT32) (*DeviceAddress) & 0xffff);\r
+  if (*NumberOfBytes > MaxNumberOfBytes) {\r
+    *NumberOfBytes = MaxNumberOfBytes;\r
+  }\r
+  //\r
+  // Compute the values to program into the BaseAddress and Count registers\r
+  // of the Slave DMA controller\r
+  //\r
+  if (ChannelNumber < 4) {\r
+    BaseAddress = (UINT32) (*DeviceAddress);\r
+    Count       = (UINT16) (*NumberOfBytes - 1);\r
+  } else {\r
+    BaseAddress = (UINT32) (((UINT32) (*DeviceAddress) & 0xff0000) | (((UINT32) (*DeviceAddress) & 0xffff) >> 1));\r
+    Count       = (UINT16) ((*NumberOfBytes - 1) >> 1);\r
+  }\r
+  //\r
+  // Program the DMA Write Single Mask Register for ChannelNumber\r
+  // Clear the DMA Byte Pointer Register\r
+  //\r
+  if (ChannelNumber < 4) {\r
+    DmaMask         = R_8237_DMA_WRSMSK_CH0_3;\r
+    DmaClear        = R_8237_DMA_CBPR_CH0_3;\r
+    DmaChannelMode  = R_8237_DMA_CHMODE_CH0_3;\r
+  } else {\r
+    DmaMask         = R_8237_DMA_WRSMSK_CH4_7;\r
+    DmaClear        = R_8237_DMA_CBPR_CH4_7;\r
+    DmaChannelMode  = R_8237_DMA_CHMODE_CH4_7;\r
+  }\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaMask,\r
+             (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03))\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaClear,\r
+             (UINT8) (B_8237_DMA_WRSMSK_CMS | (ChannelNumber & 0x03))\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (This, DmaChannelMode, DmaMode);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WriteDmaPort (\r
+             This,\r
+             mDmaRegisters[ChannelNumber].Address,\r
+             mDmaRegisters[ChannelNumber].Page,\r
+             mDmaRegisters[ChannelNumber].Count,\r
+             BaseAddress,\r
+             Count\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = WritePort (\r
+             This,\r
+             DmaMask,\r
+             (UINT8) (ChannelNumber & 0x03)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Maps a memory region for DMA\r
+\r
+  @param This                    A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param Operation               Indicates the type of DMA (slave or bus master), and if \r
+                                 the DMA operation is going to read or write to system memory. \r
+  @param ChannelNumber           The slave channel number to use for this DMA operation. \r
+                                 If Operation and ChannelAttributes shows that this device \r
+                                 performs bus mastering DMA, then this field is ignored.  \r
+                                 The legal range for this field is 0..7.  \r
+  @param ChannelAttributes       The attributes of the DMA channel to use for this DMA operation\r
+  @param HostAddress             The system memory address to map to the device.  \r
+  @param NumberOfBytes           On input the number of bytes to map.  On output the number \r
+                                 of bytes that were mapped.\r
+  @param DeviceAddress           The resulting map address for the bus master device to use \r
+                                 to access the hosts HostAddress.  \r
+  @param Mapping                 A resulting value to pass to EFI_ISA_IO.Unmap().\r
+\r
+  @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER  The Operation or HostAddress is undefined.\r
+  @retval EFI_UNSUPPORTED        The HostAddress can not be mapped as a common buffer.\r
+  @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMap (\r
+  IN     EFI_ISA_IO_PROTOCOL            *This,\r
+  IN     EFI_ISA_IO_PROTOCOL_OPERATION  Operation,\r
+  IN     UINT8                          ChannelNumber  OPTIONAL,\r
+  IN     UINT32                         ChannelAttributes,\r
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  )\r
+{\r
+  //\r
+  // Check if DMA is supported.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Set Feature Flag PcdIsaBusSupportBusMaster to FALSE to disable support for \r
+  // ISA Bus Master.\r
+  //\r
+  // So we just return EFI_UNSUPPORTED for these functions.\r
+  //\r
+  if ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0) {\r
+    return IsaIoMapOnlySupportSlaveReadWrite (\r
+             This,\r
+             Operation,\r
+             ChannelNumber,\r
+             ChannelAttributes,\r
+             HostAddress,\r
+             NumberOfBytes,\r
+             DeviceAddress,\r
+             Mapping\r
+             );\r
+\r
+  } else {\r
+    return IsaIoMapFullSupport (\r
+             This,\r
+             Operation,\r
+             ChannelNumber,\r
+             ChannelAttributes,\r
+             HostAddress,\r
+             NumberOfBytes,\r
+             DeviceAddress,\r
+             Mapping\r
+             );\r
+  }\r
+}\r
+\r
+/**\r
+  Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer mapping.\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Type               The type allocation to perform.\r
+  @param[in]  MemoryType         The type of memory to allocate.\r
+  @param[in]  Pages              The number of pages to allocate.\r
+  @param[out] HostAddress        A pointer to store the base address of the allocated range.\r
+  @param[in]  Attributes         The requested bit mask of attributes for the allocated range.\r
+\r
+  @retval EFI_SUCCESS            The requested memory pages were allocated.\r
+  @retval EFI_INVALID_PARAMETER  Type is invalid or MemoryType is invalid or HostAddress is NULL\r
+  @retval EFI_UNSUPPORTED        Attributes is unsupported or the memory range specified \r
+                                 by HostAddress, Pages, and Type is not available for common buffer use.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoAllocateBuffer (\r
+  IN  EFI_ISA_IO_PROTOCOL  *This,\r
+  IN  EFI_ALLOCATE_TYPE    Type,\r
+  IN  EFI_MEMORY_TYPE      MemoryType,\r
+  IN  UINTN                Pages,\r
+  OUT VOID                 **HostAddress,\r
+  IN  UINT64               Attributes\r
+  )\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  PhysicalAddress;\r
+\r
+  //\r
+  // Set Feature Flag PcdIsaBusOnlySupportSlaveDma to FALSE to disable support for \r
+  // ISA Bus Master.\r
+  // Or unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA.\r
+  //\r
+  if (((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) ||\r
+      ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (HostAddress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Type < AllocateAnyPages || Type >= MaxAllocateType) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData\r
+  //\r
+  if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if ((Attributes & ~(EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED)) != 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (BASE_16MB - 1);\r
+  if (Type == AllocateAddress) {\r
+    if ((UINTN) (*HostAddress) >= BASE_16MB) {\r
+      return EFI_UNSUPPORTED;\r
+    } else {\r
+      PhysicalAddress = (UINTN) (*HostAddress);\r
+    }\r
+  }\r
+\r
+  if (Type == AllocateAnyPages) {\r
+    Type = AllocateMaxAddress;\r
+  }\r
+\r
+  Status = gBS->AllocatePages (Type, MemoryType, Pages, &PhysicalAddress);\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+    return Status;\r
+  }\r
+\r
+  *HostAddress = (VOID *) (UINTN) PhysicalAddress;\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Frees memory that was allocated with EFI_ISA_IO.AllocateBuffer(). \r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Pages               The number of pages to free.\r
+  @param[in] HostAddress         The base address of the allocated range.\r
+\r
+  @retval EFI_SUCCESS            The requested memory pages were freed.\r
+  @retval EFI_INVALID_PARAMETER  The memory was not allocated with EFI_ISA_IO.AllocateBufer().\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoFreeBuffer (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINTN                Pages,\r
+  IN VOID                 *HostAddress\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Set Feature Flag PcdIsaBusOnlySupportSlaveDma to FALSE to disable support for \r
+  // ISA Bus Master.\r
+  // Or unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA.\r
+  //\r
+  if (((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_SUPPORT_DMA) == 0) ||\r
+      ((PcdGet8 (PcdIsaBusSupportedFeatures) & PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA) != 0)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Status = gBS->FreePages (\r
+                  (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress,\r
+                  Pages\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR\r
+      );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.h b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIo.h
new file mode 100644 (file)
index 0000000..cc4a1f8
--- /dev/null
@@ -0,0 +1,331 @@
+/** @file\r
+  The header file for EFI_ISA_IO protocol implementation.\r
+  \r
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ISA_IO_H_\r
+#define _ISA_IO_H_\r
+\r
+#include "IsaDriver.h"\r
+\r
+//\r
+// Bits definition of PcdIsaBusSupportedFeatures\r
+//\r
+#define PCD_ISA_BUS_SUPPORT_DMA                  BIT0\r
+#define PCD_ISA_BUS_ONLY_SUPPORT_SLAVE_DMA       BIT1\r
+#define PCD_ISA_BUS_SUPPORT_ISA_MEMORY           BIT2\r
+\r
+//\r
+// ISA I/O Support Function Prototypes\r
+//\r
+\r
+/**\r
+  Verifies access to an ISA device\r
+\r
+  @param[in] IsaIoDevice         The ISA device to be verified.\r
+  @param[in] Type                The Access type. The input must be either IsaAccessTypeMem or IsaAccessTypeIo.\r
+  @param[in] Width               The width of the memory operation.\r
+  @param[in] Count               The number of memory operations to perform. \r
+  @param[in] Offset              The offset in ISA memory space to start the memory operation.  \r
+  \r
+  @retval EFI_SUCCESS            Verify success.\r
+  @retval EFI_INVALID_PARAMETER  One of the parameters has an invalid value.\r
+  @retval EFI_UNSUPPORTED        The device ont support the access type.\r
+**/\r
+EFI_STATUS\r
+IsaIoVerifyAccess (\r
+  IN ISA_IO_DEVICE              *IsaIoDevice,\r
+  IN ISA_ACCESS_TYPE            Type,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINTN                      Count,\r
+  IN UINT32                     Offset\r
+  );\r
+  \r
+/**\r
+  Performs an ISA I/O Read Cycle\r
+\r
+  @param[in]  This              A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width             Specifies the width of the I/O operation.\r
+  @param[in]  Offset            The offset in ISA I/O space to start the I/O operation.  \r
+  @param[in]  Count             The number of I/O operations to perform. \r
+  @param[out] Buffer            The destination buffer to store the results\r
+\r
+  @retval EFI_SUCCESS           The data was read from the device sucessfully.\r
+  @retval EFI_UNSUPPORTED       The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoIoRead (\r
+  IN  EFI_ISA_IO_PROTOCOL        *This,\r
+  IN  EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT32                     Offset,\r
+  IN  UINTN                      Count,\r
+  OUT VOID                       *Buffer\r
+  );\r
+\r
+/**\r
+  Performs an ISA I/O Write Cycle\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Width               Specifies the width of the I/O operation.\r
+  @param[in] Offset              The offset in ISA I/O space to start the I/O operation.  \r
+  @param[in] Count               The number of I/O operations to perform. \r
+  @param[in] Buffer              The source buffer to write data from\r
+\r
+  @retval EFI_SUCCESS            The data was writen to the device sucessfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoIoWrite (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     Offset,\r
+  IN UINTN                      Count,\r
+  IN VOID                       *Buffer\r
+  );\r
+\r
+/**\r
+  Maps a memory region for DMA\r
+\r
+  @param This                    A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param Operation               Indicates the type of DMA (slave or bus master), and if \r
+                                 the DMA operation is going to read or write to system memory. \r
+  @param ChannelNumber           The slave channel number to use for this DMA operation. \r
+                                 If Operation and ChannelAttributes shows that this device \r
+                                 performs bus mastering DMA, then this field is ignored.  \r
+                                 The legal range for this field is 0..7.  \r
+  @param ChannelAttributes       The attributes of the DMA channel to use for this DMA operation\r
+  @param HostAddress             The system memory address to map to the device.  \r
+  @param NumberOfBytes           On input the number of bytes to map.  On output the number \r
+                                 of bytes that were mapped.\r
+  @param DeviceAddress           The resulting map address for the bus master device to use \r
+                                 to access the hosts HostAddress.  \r
+  @param Mapping                 A resulting value to pass to EFI_ISA_IO.Unmap().\r
+\r
+  @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.\r
+  @retval EFI_INVALID_PARAMETER  The Operation or HostAddress is undefined.\r
+  @retval EFI_UNSUPPORTED        The HostAddress can not be mapped as a common buffer.\r
+  @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMap (\r
+  IN     EFI_ISA_IO_PROTOCOL            *This,\r
+  IN     EFI_ISA_IO_PROTOCOL_OPERATION  Operation,\r
+  IN     UINT8                          ChannelNumber  OPTIONAL,\r
+  IN     UINT32                         ChannelAttributes,\r
+  IN     VOID                           *HostAddress,\r
+  IN OUT UINTN                          *NumberOfBytes,\r
+  OUT    EFI_PHYSICAL_ADDRESS           *DeviceAddress,\r
+  OUT    VOID                           **Mapping\r
+  );\r
+\r
+/**\r
+  Unmaps a memory region for DMA\r
+\r
+  @param[in] This           A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Mapping        The mapping value returned from EFI_ISA_IO.Map().\r
+\r
+  @retval EFI_SUCCESS       The range was unmapped.\r
+  @retval EFI_DEVICE_ERROR  The data was not committed to the target system memory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoUnmap (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN VOID                 *Mapping\r
+  );\r
+\r
+/**\r
+  Flushes any posted write data to the system memory.\r
+\r
+  @param[in] This             A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+\r
+  @retval  EFI_SUCCESS        The buffers were flushed.\r
+  @retval  EFI_DEVICE_ERROR   The buffers were not flushed due to a hardware error.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoFlush (\r
+  IN EFI_ISA_IO_PROTOCOL  *This\r
+  );\r
+\r
+/**\r
+  Writes I/O operation base address and count number to a 8 bit I/O Port.\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] AddrOffset          The address' offset.\r
+  @param[in] PageOffset          The page's offest.\r
+  @param[in] CountOffset         The count's offset.\r
+  @param[in] BaseAddress         The base address.\r
+  @param[in] Count               The number of I/O operations to perform. \r
+  \r
+  @retval EFI_SUCCESS            Success.\r
+  @retval EFI_INVALID_PARAMETER  Parameter is invalid.\r
+  @retval EFI_UNSUPPORTED        The address range specified by these Offsets and Count is not valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+WriteDmaPort (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINT32               AddrOffset,\r
+  IN UINT32               PageOffset,\r
+  IN UINT32               CountOffset,\r
+  IN UINT32               BaseAddress,\r
+  IN UINT16               Count\r
+  );\r
+\r
+/**\r
+  Writes an 8-bit I/O Port\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Offset              The offset in ISA IO space to start the IO operation.  \r
+  @param[in] Value               The data to write port.\r
+\r
+  @retval EFI_SUCCESS            Success.\r
+  @retval EFI_INVALID_PARAMETER  Parameter is invalid.\r
+  @retval EFI_UNSUPPORTED        The address range specified by Offset is not valid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+WritePort (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINT32               Offset,\r
+  IN UINT8                Value\r
+  );    \r
+\r
+/**\r
+  Performs an ISA Memory Read Cycle\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width              Specifies the width of the memory operation.\r
+  @param[in]  Offset             The offset in ISA memory space to start the memory operation.  \r
+  @param[in]  Count              The number of memory operations to perform. \r
+  @param[out] Buffer             The destination buffer to store the results\r
\r
+  @retval EFI_SUCCESS            The data was read from the device successfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMemRead (\r
+  IN  EFI_ISA_IO_PROTOCOL        *This,\r
+  IN  EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN  UINT32                     Offset,\r
+  IN  UINTN                      Count,\r
+  OUT VOID                       *Buffer\r
+  );\r
+\r
+\r
+/**\r
+  Performs an ISA Memory Write Cycle\r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.  \r
+  @param[in] Width               Specifies the width of the memory operation.\r
+  @param[in] Offset              The offset in ISA memory space to start the memory operation.  \r
+  @param[in] Count               The number of memory operations to perform. \r
+  @param[in] Buffer              The source buffer to write data from\r
+\r
+  @retval EFI_SUCCESS            The data was written to the device sucessfully.\r
+  @retval EFI_UNSUPPORTED        The Offset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoMemWrite (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     Offset,\r
+  IN UINTN                      Count,\r
+  IN VOID                       *Buffer\r
+  );\r
+\r
+/**\r
+  Copy one region of ISA memory space to another region of ISA memory space on the ISA controller.\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Width              Specifies the width of the memory copy operation.\r
+  @param[in]  DestOffset         The offset of the destination \r
+  @param[in]  SrcOffset          The offset of the source\r
+  @param[in]  Count              The number of memory copy  operations to perform\r
+\r
+  @retval EFI_SUCCESS            The data was copied sucessfully.\r
+  @retval EFI_UNSUPPORTED        The DestOffset or SrcOffset is not valid for this device.\r
+  @retval EFI_INVALID_PARAMETER  Width or Count, or both, were invalid.\r
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoCopyMem (\r
+  IN EFI_ISA_IO_PROTOCOL        *This,\r
+  IN EFI_ISA_IO_PROTOCOL_WIDTH  Width,\r
+  IN UINT32                     DestOffset,\r
+  IN UINT32                     SrcOffset,\r
+  IN UINTN                      Count\r
+  );\r
+\r
+/**\r
+  Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer mapping.\r
+\r
+  @param[in]  This               A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in]  Type               The type allocation to perform.\r
+  @param[in]  MemoryType         The type of memory to allocate.\r
+  @param[in]  Pages              The number of pages to allocate.\r
+  @param[out] HostAddress        A pointer to store the base address of the allocated range.\r
+  @param[in]  Attributes         The requested bit mask of attributes for the allocated range.\r
+\r
+  @retval EFI_SUCCESS            The requested memory pages were allocated.\r
+  @retval EFI_INVALID_PARAMETER  Type is invalid or MemoryType is invalid or HostAddress is NULL\r
+  @retval EFI_UNSUPPORTED        Attributes is unsupported or the memory range specified \r
+                                 by HostAddress, Pages, and Type is not available for common buffer use.\r
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoAllocateBuffer (\r
+  IN  EFI_ISA_IO_PROTOCOL  *This,\r
+  IN  EFI_ALLOCATE_TYPE    Type,\r
+  IN  EFI_MEMORY_TYPE      MemoryType,\r
+  IN  UINTN                Pages,\r
+  OUT VOID                 **HostAddress,\r
+  IN  UINT64               Attributes\r
+  );\r
+\r
+/**\r
+  Frees memory that was allocated with EFI_ISA_IO.AllocateBuffer(). \r
+\r
+  @param[in] This                A pointer to the EFI_ISA_IO_PROTOCOL instance.\r
+  @param[in] Pages               The number of pages to free.\r
+  @param[in] HostAddress         The base address of the allocated range.\r
+\r
+  @retval EFI_SUCCESS            The requested memory pages were freed.\r
+  @retval EFI_INVALID_PARAMETER  The memory was not allocated with EFI_ISA_IO.AllocateBufer().\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IsaIoFreeBuffer (\r
+  IN EFI_ISA_IO_PROTOCOL  *This,\r
+  IN UINTN                Pages,\r
+  IN VOID                 *HostAddress\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf b/IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf
new file mode 100644 (file)
index 0000000..4caf338
--- /dev/null
@@ -0,0 +1,67 @@
+## @file\r
+# Component description file for IsaIoDxe module.\r
+#\r
+# Produces an instance of the ISA I/O Protocol for every SIO controller.\r
+#\r
+# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = IsaIoDxe\r
+  FILE_GUID                      = 61AD3083-DCAD-4850-A50C-73B23B3B14F9\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializeIsaIo\r
+\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#  DRIVER_BINDING                = gIsaIoDriver\r
+#  COMPONENT_NAME                = gIsaIoComponentName;\r
+#  COMPONENT_NAME2               = gIsaIoComponentName2;\r
+#\r
+\r
+[Sources]\r
+  ComponentName.h\r
+  ComponentName.c\r
+  IsaIo.h\r
+  IsaIo.c\r
+  IsaDriver.h\r
+  IsaDriver.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  PcdLib\r
+  ReportStatusCodeLib\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  BaseMemoryLib\r
+  DevicePathLib\r
+  UefiLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+\r
+[Protocols]\r
+  gEfiIsaIoProtocolGuid                         # PROTOCOL BY_START\r
+  gEfiSioProtocolGuid                           # PROTOCOL TO_START\r
+  gEfiPciIoProtocolGuid                         # PROTOCOL TO_START\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL TO_START\r
+  gEfiGenericMemTestProtocolGuid                # PROTOCOL TO_START\r
+\r
+[Pcd]\r
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdIsaBusSupportedFeatures\r
+\r
+\r
index 8cb6430500a5db1d76dc3d888a33b1ccaf6fec9e..677de6d36161cb80c2d462def566fe38248340c0 100644 (file)
 \r
   IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf\r
   IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf\r
+  IntelFrameworkModulePkg/Bus/Isa/IsaIoDxe/IsaIoDxe.inf\r
   IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf\r
   IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf\r
   IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf\r