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