diff options
Diffstat (limited to 'IntelFrameworkModulePkg/Bus')
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/CommonHeader.h | 56 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.c | 141 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.h | 92 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/EntryPoint.c | 58 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaBus.h | 253 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaIo.h | 163 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c | 653 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf | 145 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.msa | 142 | ||||
-rw-r--r-- | IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaIo.c | 1646 |
10 files changed, 3349 insertions, 0 deletions
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/CommonHeader.h b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/CommonHeader.h new file mode 100644 index 0000000000..85e65e48c5 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/CommonHeader.h @@ -0,0 +1,56 @@ +/**@file
+ Common header file shared by all source files.
+
+ This file includes package header files, library classes and protocol, PPI & GUID definitions.
+
+ Copyright (c) 2006 - 2007, Intel Corporation.
+ All rights reserved.
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+**/
+
+#ifndef __COMMON_HEADER_H_
+#define __COMMON_HEADER_H_
+
+
+//
+// The package level header files this module uses
+//
+#include <PiDxe.h>
+#include <FrameworkDxe.h>
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Protocol/PciIo.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/IsaIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/IsaAcpi.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/GenericMemoryTest.h>
+#include <Guid/StatusCodeDataTypeId.h>
+//
+// The Library classes this module consumes
+//
+#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/BootScriptLib.h>
+#include <Library/PcdLib.h>
+//
+// Driver Binding Externs
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver;
+extern EFI_COMPONENT_NAME_PROTOCOL gIsaBusComponentName;
+
+#endif
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.c b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.c new file mode 100644 index 0000000000..186aa5fc54 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.c @@ -0,0 +1,141 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation. All rights reserved. <BR>
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "ComponentName.h"
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gIsaBusComponentName = {
+ IsaBusComponentNameGetDriverName,
+ IsaBusComponentNameGetControllerName,
+ "eng"
+};
+
+STATIC EFI_UNICODE_STRING_TABLE mIsaBusDriverNameTable[] = {
+ {
+ "eng",
+ L"ISA Bus Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+EFI_STATUS
+EFIAPI
+IsaBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gIsaBusComponentName.SupportedLanguages,
+ mIsaBusDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+IsaBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language
+ specified by Language from the point of view of the
+ driver specified by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.h b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.h new file mode 100644 index 0000000000..bca36505a7 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/ComponentName.h @@ -0,0 +1,92 @@ +/*++
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ ComponentName.h
+
+Abstract:
+
+
+Revision History:
+
+--*/
+
+#ifndef _EFI_ISA_BUS_COMPONENT_NAME_H
+#define _EFI_ISA_BUS_COMPONENT_NAME_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+extern EFI_COMPONENT_NAME_PROTOCOL gIsaBusComponentName;
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+IsaBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Language - GC_TODO: add argument description
+ DriverName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+IsaBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ControllerHandle - GC_TODO: add argument description
+ ChildHandle - GC_TODO: add argument description
+ Language - GC_TODO: add argument description
+ ControllerName - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/EntryPoint.c b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/EntryPoint.c new file mode 100644 index 0000000000..ae5146ab54 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/EntryPoint.c @@ -0,0 +1,58 @@ +/**@file
+ Entry Point Source file.
+
+ This file contains the user entry point
+
+ Copyright (c) 2006 - 2007, Intel Corporation.
+ All rights reserved.
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+**/
+
+
+//
+// Include common header file for this module.
+//
+#include "InternalIsaBus.h"
+
+/**
+ The user Entry Point for module IsaBus. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeIsaBus(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallAllDriverProtocols (
+ ImageHandle,
+ SystemTable,
+ &gIsaBusControllerDriver,
+ ImageHandle,
+ &gIsaBusComponentName,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaBus.h b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaBus.h new file mode 100644 index 0000000000..27bfb7a4e0 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaBus.h @@ -0,0 +1,253 @@ +/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ IsaBus.h
+
+Abstract:
+
+ The header file for ISA bus driver
+
+Revision History:
+
+--*/
+
+#ifndef _EFI_ISA_BUS_H
+#define _EFI_ISA_BUS_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "ComponentName.h"
+
+extern EFI_ISA_IO_PROTOCOL IsaIoInterface;
+
+typedef enum {
+ IsaAccessTypeUnknown,
+ IsaAccessTypeIo,
+ IsaAccessTypeMem,
+ IsaAccessTypeMaxType
+} ISA_ACCESS_TYPE;
+
+//
+// 16 MB Memory Range
+//
+#define ISA_MAX_MEMORY_ADDRESS 0x1000000
+//
+// 64K I/O Range
+//
+#define ISA_MAX_IO_ADDRESS 0x10000
+
+typedef struct {
+ UINT8 Address;
+ UINT8 Page;
+ UINT8 Count;
+} EFI_ISA_DMA_REGISTERS;
+
+//
+// ISA I/O Device Structure
+//
+#define ISA_IO_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('i', 's', 'a', 'i')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_ISA_IO_PROTOCOL IsaIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ 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)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver;
+
+//
+// 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
+//
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function checks to see if a controller can be managed by the ISA Bus
+ Driver. This is done by checking to see if the controller supports the
+ EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration
+ Header to see if the device is a PCI to ISA bridge. The class code of
+ PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of the device to check.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - The device is supported by this driver.
+ EFI_UNSUPPORTED - The device is not supported by this driver.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function tells the ISA Bus Driver to start managing a PCI to ISA
+ Bridge controller.
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - A handle to the device being started.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - The device was started.
+ EFI_UNSUPPORTED - The device is not supported.
+ EFI_DEVICE_ERROR - The device could not be started due to a device error.
+ EFI_ALREADY_STARTED - The device has already been started.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE * ChildHandleBuffer OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function tells the ISA Bus Driver to stop managing a PCI to ISA
+ Bridge controller.
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - A handle to the device being stopped.
+ NumberOfChindren - The number of child device handles in ChildHandleBuffer.
+ ChildHandleBuffer - An array of child handles to be freed.
+
+
+ Returns:
+
+ EFI_SUCCESS - The device was stopped.
+ EFI_DEVICE_ERROR - The device could not be stopped due to a device error.
+ EFI_NOT_STARTED - The device has not been started.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+
+--*/
+;
+
+//
+// Function Prototypes
+//
+
+EFI_STATUS
+IsaCreateDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList,
+ OUT EFI_DEVICE_PATH_PROTOCOL **ChildDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Create ISA device found by IsaPnpProtocol
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of ISA bus controller(PCI to ISA bridge)
+ PciIo - The Pointer to the PCI protocol
+ ParentDevicePath - Device path of the ISA bus controller
+ IsaDeviceResourceList - The resource list of the ISA device
+ ChildDevicePath - The pointer to the child device.
+
+ Returns:
+
+ EFI_SUCCESS - Create the child device.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+ EFI_DEVICE_ERROR - Can not create child device.
+
+--*/
+;
+
+EFI_STATUS
+InitializeIsaIoInstance (
+ IN ISA_IO_DEVICE *IsaIoDevice,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDevice
+ )
+/*++
+
+Routine Description:
+
+ Initializes an ISA I/O Instance
+
+Arguments:
+
+ IsaIoDevice - The iso device to be initialized.
+ IsaDevice - The resource list.
+
+Returns:
+
+ EFI_SUCCESS - Initial success.
+
+--*/
+;
+
+#endif
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaIo.h b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaIo.h new file mode 100644 index 0000000000..d344058fb9 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/InternalIsaIo.h @@ -0,0 +1,163 @@ +/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ IsaIo.h
+
+Abstract:
+
+ The header file for EFI_ISA_IO protocol implementation.
+
+--*/
+
+#ifndef _EFI_ISA_IO_LOCAL_H
+#define _EFI_ISA_IO_LOCAL_H
+
+//
+// Include common header file for this module.
+//
+#include "CommonHeader.h"
+
+#include "InternalIsaBus.h"
+
+//
+// ISA I/O Support Function Prototypes
+//
+
+EFI_STATUS
+IsaIoVerifyAccess (
+ IN ISA_IO_DEVICE *IsaIoDevice,
+ IN ISA_ACCESS_TYPE Type,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN OUT UINT32 *Offset
+ );
+
+EFI_STATUS
+EFIAPI
+IsaIoIoRead (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+IsaIoIoWrite (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+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
+ );
+
+EFI_STATUS
+EFIAPI
+IsaIoUnmap (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+EFI_STATUS
+EFIAPI
+IsaIoFlush (
+ IN EFI_ISA_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+ReportErrorStatusCode (
+ EFI_STATUS_CODE_VALUE code
+ );
+
+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
+WritePort (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINT32 Offset,
+ IN UINT8 Value
+ );
+
+EFI_STATUS
+EFIAPI
+IsaIoMemRead (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+
+EFI_STATUS
+EFIAPI
+IsaIoMemWrite (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+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
+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
+EFIAPI
+IsaIoFreeBuffer (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ );
+
+#endif
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c new file mode 100644 index 0000000000..daee1fb510 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.c @@ -0,0 +1,653 @@ +/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ IsaBus.c
+
+Abstract:
+
+ Discovers all the ISA Controllers and their resources by using the ISA PnP
+ Protocol, produces an instance of the ISA I/O Protocol for every ISA
+ Controller found, loads and initializes all ISA Device Drivers, matches ISA
+ Device Drivers with their respective ISA Controllers in a deterministic
+ manner, and informs a ISA Device Driver when it is to start managing an ISA
+ Controller.
+
+Revision History:
+
+--*/
+
+#include "InternalIsaBus.h"
+
+//
+// ISA Bus Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL gIsaBusControllerDriver = {
+ IsaBusControllerDriverSupported,
+ IsaBusControllerDriverStart,
+ IsaBusControllerDriverStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function checks to see if a controller can be managed by the ISA Bus
+ Driver. This is done by checking to see if the controller supports the
+ EFI_PCI_IO_PROTOCOL protocol, and then looking at the PCI Configuration
+ Header to see if the device is a PCI to ISA bridge. The class code of
+ PCI to ISA bridge: Base class 06h, Sub class 01h Interface 00h
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of the device to check.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - The device is supported by this driver.
+ EFI_UNSUPPORTED - The device is not supported by this driver.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
+
+ //
+ // If RemainingDevicePath is not NULL, it should verify that the first device
+ // path node in RemainingDevicePath is an ACPI Device path node
+ //
+ if (RemainingDevicePath != NULL) {
+ if (RemainingDevicePath->Type != ACPI_DEVICE_PATH) {
+ return EFI_UNSUPPORTED;
+ } else if (RemainingDevicePath->SubType == ACPI_DP) {
+ if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_HID_DEVICE_PATH)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else if (RemainingDevicePath->SubType == ACPI_EXTENDED_DP) {
+ if (DevicePathNodeLength (RemainingDevicePath) != sizeof (ACPI_EXTENDED_HID_DEVICE_PATH)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ //
+ // Test the existence of DEVICE_PATH protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Get the Isa Acpi protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaAcpiProtocolGuid,
+ (VOID **) &IsaAcpi,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiIsaAcpiProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function tells the ISA Bus Driver to start managing a PCI to ISA
+ Bridge controller.
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - A handle to the device being started.
+ RemainingDevicePath - A pointer to the remaining portion of a device path.
+
+ Returns:
+
+ EFI_SUCCESS - The device was started.
+ EFI_UNSUPPORTED - The device is not supported.
+ EFI_DEVICE_ERROR - The device could not be started due to a device error.
+ EFI_ALREADY_STARTED - The device has already been started.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_ISA_ACPI_PROTOCOL *IsaAcpi;
+ EFI_ISA_ACPI_DEVICE_ID *IsaDevice;
+ EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
+ EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest;
+
+ //
+ // Local variables declaration for StatusCode reporting
+ //
+ EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA AllocFailExtendedData;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathData;
+
+ BootScriptSaveInformationAsciiString (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ "IsaBusBindingStartBegin"
+ );
+
+ //
+ // Initialize status code structure
+ //
+ AllocFailExtendedData.DataHeader.HeaderSize = sizeof (EFI_STATUS_CODE_DATA);
+ AllocFailExtendedData.DataHeader.Size = sizeof (EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA) - sizeof (EFI_STATUS_CODE_DATA);
+ CopyMem (
+ &AllocFailExtendedData.DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+
+ //
+ // Open Device Path Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+ //
+ // Open Pci IO Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Close opened protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+ //
+ // Open ISA Acpi Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaAcpiProtocolGuid,
+ (VOID **) &IsaAcpi,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ //
+ // Close opened protocol
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+ //
+ // The IsaBus driver will use memory below 16M, which is not tested yet,
+ // so call CompatibleRangeTest to test them. Since memory below 1M should
+ // be reserved to CSM, and 15M~16M might be reserved for Isa hole, test 1M
+ // ~15M here
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiGenericMemTestProtocolGuid,
+ NULL,
+ (VOID **) &GenMemoryTest
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = GenMemoryTest->CompatibleRangeTest (
+ GenMemoryTest,
+ 0x100000,
+ 0xE00000
+ );
+ }
+ //
+ // Report Status Code here since we will initialize the host controller
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),
+ ParentDevicePath
+ );
+
+ //
+ // first init ISA interface
+ //
+ IsaAcpi->InterfaceInit (IsaAcpi);
+
+ //
+ // Report Status Code here since we will enable the host controller
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),
+ ParentDevicePath
+ );
+
+ //
+ // Create each ISA device handle in this ISA bus
+ //
+ IsaDevice = NULL;
+ do {
+ Status = IsaAcpi->DeviceEnumerate (IsaAcpi, &IsaDevice);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ //
+ // Get current resource of this ISA device
+ //
+ ResourceList = NULL;
+ Status = IsaAcpi->GetCurResource (IsaAcpi, IsaDevice, &ResourceList);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Create handle for this ISA device
+ //
+ Status = IsaCreateDevice (
+ This,
+ Controller,
+ PciIo,
+ ParentDevicePath,
+ ResourceList,
+ &DevicePathData
+ //&AllocFailExtendedData.DevicePath
+ );
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+ //
+ // Initialize ISA device
+ //
+ IsaAcpi->InitDevice (IsaAcpi, IsaDevice);
+
+ //
+ // Set resources for this ISA device
+ //
+ Status = IsaAcpi->SetResource (IsaAcpi, IsaDevice, ResourceList);
+
+ //
+ // Report Status Code here when failed to resource conflicts
+ //
+ if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) {
+ //
+ // It's hard to tell which resource conflicts
+ //
+ AllocFailExtendedData.Bar = 0;
+ AllocFailExtendedData.ReqRes = NULL;
+ AllocFailExtendedData.AllocRes = NULL;
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE,
+ (EFI_IO_BUS_LPC | EFI_IOB_EC_RESOURCE_CONFLICT),
+ DevicePathData
+ );
+
+ }
+ //
+ // Set power for this ISA device
+ //
+ IsaAcpi->SetPower (IsaAcpi, IsaDevice, TRUE);
+
+ //
+ // Enable this ISA device
+ //
+ IsaAcpi->EnableDevice (IsaAcpi, IsaDevice, TRUE);
+
+ } while (TRUE);
+
+ BootScriptSaveInformationAsciiString (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ "IsaBusBindingStartEnd"
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaBusControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE * ChildHandleBuffer OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ This function tells the ISA Bus Driver to stop managing a PCI to ISA
+ Bridge controller.
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - A handle to the device being stopped.
+ NumberOfChindren - The number of child device handles in ChildHandleBuffer.
+ ChildHandleBuffer - An array of child handles to be freed.
+
+
+ Returns:
+
+ EFI_SUCCESS - The device was stopped.
+ EFI_DEVICE_ERROR - The device could not be stopped due to a device error.
+ EFI_NOT_STARTED - The device has not been started.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ ISA_IO_DEVICE *IsaIoDevice;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiIsaAcpiProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+ }
+ //
+ // Complete all outstanding transactions to Controller.
+ // Don't allow any new transaction to Controller to be started.
+ //
+ //
+ // Stop all the children
+ // Find all the ISA devices that were discovered on this PCI to ISA Bridge
+ // with the Start() function.
+ //
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+
+ IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (IsaIo);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ IsaIoDevice->DevicePath,
+ &gEfiIsaIoProtocolGuid,
+ &IsaIoDevice->IsaIo,
+ NULL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Close the child handle
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]
+ );
+
+ gBS->FreePool (IsaIoDevice->DevicePath);
+ gBS->FreePool (IsaIoDevice);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+//
+// Internal Function
+//
+EFI_STATUS
+IsaCreateDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList,
+ OUT EFI_DEVICE_PATH_PROTOCOL **ChildDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Create ISA device found by IsaPnpProtocol
+
+ Arguments:
+
+ This - The EFI_DRIVER_BINDING_PROTOCOL instance.
+ Controller - The handle of ISA bus controller(PCI to ISA bridge)
+ PciIo - The Pointer to the PCI protocol
+ ParentDevicePath - Device path of the ISA bus controller
+ IsaDeviceResourceList - The resource list of the ISA device
+ ChildDevicePath - The pointer to the child device.
+
+ Returns:
+
+ EFI_SUCCESS - Create the child device.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of
+ resources.
+ EFI_DEVICE_ERROR - Can not create child device.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+ EFI_DEV_PATH Node;
+
+ //
+ // Initialize the PCI_IO_DEVICE structure
+ //
+ IsaIoDevice = AllocateZeroPool (sizeof (ISA_IO_DEVICE));
+ if (IsaIoDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IsaIoDevice->Signature = ISA_IO_DEVICE_SIGNATURE;
+ IsaIoDevice->Handle = NULL;
+ IsaIoDevice->PciIo = PciIo;
+
+ //
+ // Initialize the ISA I/O instance structure
+ //
+ Status = InitializeIsaIoInstance (IsaIoDevice, IsaDeviceResourceList);
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (IsaIoDevice);
+ return Status;
+ }
+ //
+ // Build the child device path
+ //
+ Node.DevPath.Type = ACPI_DEVICE_PATH;
+ Node.DevPath.SubType = ACPI_DP;
+ SetDevicePathNodeLength (&Node.DevPath, sizeof (ACPI_HID_DEVICE_PATH));
+ Node.Acpi.HID = IsaDeviceResourceList->Device.HID;
+ Node.Acpi.UID = IsaDeviceResourceList->Device.UID;
+
+ IsaIoDevice->DevicePath = AppendDevicePathNode (
+ ParentDevicePath,
+ &Node.DevPath
+ );
+
+ if (IsaIoDevice->DevicePath == NULL) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ *ChildDevicePath = IsaIoDevice->DevicePath;
+
+ //
+ // Create a child handle and attach the DevicePath,
+ // PCI I/O, and Controller State
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &IsaIoDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ IsaIoDevice->DevicePath,
+ &gEfiIsaIoProtocolGuid,
+ &IsaIoDevice->IsaIo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ IsaIoDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ IsaIoDevice->Handle,
+ &gEfiDevicePathProtocolGuid,
+ IsaIoDevice->DevicePath,
+ &gEfiIsaIoProtocolGuid,
+ &IsaIoDevice->IsaIo,
+ NULL
+ );
+ }
+
+Done:
+
+ if (EFI_ERROR (Status)) {
+ if (IsaIoDevice->DevicePath != NULL) {
+ gBS->FreePool (IsaIoDevice->DevicePath);
+ }
+
+ gBS->FreePool (IsaIoDevice);
+ }
+
+ return Status;
+}
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf new file mode 100644 index 0000000000..1d4c596d17 --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.inf @@ -0,0 +1,145 @@ +#/** @file
+# Component description file for IsaBus module.
+#
+# Discovers all the ISA Controllers and their resources by using the ISA PnP
+# Protocol, produces an instance of the ISA I/O Protocol for every ISA
+# Controller found, loads and initializes all ISA Device Drivers, matches ISA
+# Device Drivers with their respective ISA Controllers in a deterministic
+# manner, and informs a ISA Device Driver when it is to start managing an ISA
+# Controller.
+# Copyright (c) 2006 - 2007, Intel Corporation.
+#
+# All rights reserved.
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IsaBus
+ FILE_GUID = 240612B5-A063-11d4-9A3A-0090273FC14D
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+ ENTRY_POINT = InitializeIsaBus
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gIsaBusControllerDriver
+# COMPONENT_NAME = gIsaBusComponentName
+#
+
+################################################################################
+#
+# Sources Section - list of files that are required for the build to succeed.
+#
+################################################################################
+
+[Sources.common]
+ ComponentName.c
+ IsaIo.c
+ IsaBus.c
+ IsaIo.h
+ IsaBus.h
+ IsaAcpi.h
+ ComponentName.h
+ CommonHeader.h
+ EntryPoint.c
+
+
+################################################################################
+#
+# Includes Section - list of Include locations that are required for
+# this module.
+#
+################################################################################
+
+[Includes]
+
+################################################################################
+#
+# Package Dependency Section - list of Package files that are required for
+# this module.
+#
+################################################################################
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+
+################################################################################
+#
+# Library Class Section - list of Library Classes that are required for
+# this module.
+#
+################################################################################
+
+[LibraryClasses]
+ PcdLib
+ BootScriptLib
+ ReportStatusCodeLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ DevicePathLib
+ UefiLib
+ UefiDriverEntryPoint
+ DebugLib
+
+
+################################################################################
+#
+# Guid C Name Section - list of Guids that this module uses or produces.
+#
+################################################################################
+
+[Guids]
+ gEfiStatusCodeSpecificDataGuid # ALWAYS_CONSUMED
+
+
+################################################################################
+#
+# Protocol C Name Section - list of Protocol and Protocol Notify C Names
+# that this module uses or produces.
+#
+################################################################################
+
+[Protocols]
+ gEfiIsaIoProtocolGuid # PROTOCOL BY_START
+ gEfiIsaAcpiProtocolGuid # PROTOCOL TO_START
+ gEfiPciIoProtocolGuid # PROTOCOL TO_START
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START
+ gEfiGenericMemTestProtocolGuid # PROTOCOL TO_START
+
+
+################################################################################
+#
+# Pcd FEATURE_FLAG - list of PCDs that this module is coded for.
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ PcdIsaBusOnlySupportSlaveDma|gEfiIntelFrameworkModulePkgTokenSpaceGuid
+ PcdIsaBusSupportDma|gEfiIntelFrameworkModulePkgTokenSpaceGuid
+ PcdIsaBusSupportIsaMemory|gEfiIntelFrameworkModulePkgTokenSpaceGuid
+
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.msa b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.msa new file mode 100644 index 0000000000..cc2cf6a33a --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBus.msa @@ -0,0 +1,142 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd" xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>IsaBus</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>240612B5-A063-11d4-9A3A-0090273FC14D</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for IsaBus module.</Abstract>
+ <Description>Discovers all the ISA Controllers and their resources by using the ISA PnP + Protocol, produces an instance of the ISA I/O Protocol for every ISA + Controller found, loads and initializes all ISA Device Drivers, matches ISA + Device Drivers with their respective ISA Controllers in a deterministic + manner, and informs a ISA Device Driver when it is to start managing an ISA + Controller.</Description>
+ <Copyright>Copyright (c) 2006 - 2007, Intel Corporation.</Copyright>
+ <License>All rights reserved. + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>IsaBus</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DevicePathLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>ReportStatusCodeLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BootScriptLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>ComponentName.h</Filename>
+ <Filename>IsaAcpi.h</Filename>
+ <Filename>IsaBus.h</Filename>
+ <Filename>IsaIo.h</Filename>
+ <Filename>IsaBus.c</Filename>
+ <Filename>IsaIo.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ <Package PackageGuid="bea835f9-fd62-464a-81ff-f3a806360c6b"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiGenericMemTestProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiIsaAcpiProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiIsaIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiStatusCodeSpecificDataGuid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gIsaBusControllerDriver</DriverBinding>
+ <ComponentName>gIsaBusComponentName</ComponentName>
+ </Extern>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdIsaBusSupportIsaMemory</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <DefaultValue>TRUE</DefaultValue>
+ <HelpText>This feature flag is used to enable the implementation for interface + _EFI_ISA_IO_PROTOCOL.Mem.Read, _EFI_ISA_IO_PROTOCOL.Mem.Write and _EFI_ISA_IO_PROTOCOL.CopyMem. + If it is unset, these interfaces will return EFI_UNSUPPORTED. When it is disabled, + it is will save code size if a platform does not have ISA device with ISA memory.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdIsaBusSupportDma</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <DefaultValue>TRUE</DefaultValue>
+ <HelpText>This feature flag is used to enable the implementation for interface + _EFI_ISA_IO_PROTOCOL.AllocateBuffer, _EFI_ISA_IO_PROTOCOL.FreeBuffer, _EFI_ISA_IO_PROTOCOL.Map + and _EFI_ISA_IO_PROTOCOL.UnMap. If it is unset, these interfaces will return EFI_UNSUPPORTED. + It is useful to save code size if a platform does not have ISA device which did DMA transfer.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FEATURE_FLAG" Usage="ALWAYS_CONSUMED">
+ <C_Name>PcdIsaBusOnlySupportSlaveDma</C_Name>
+ <TokenSpaceGuidCName>gEfiGenericPlatformTokenSpaceGuid</TokenSpaceGuidCName>
+ <DefaultValue>FALSE</DefaultValue>
+ <HelpText>This feature flag is used to enable the implementation for interface + _EFI_ISA_IO_PROTOCOL.Map and _EFI_ISA_IO_PROTOCOL.UnMap to only support Slave DMA + transfers. In addition, unsetting this feature flag also make AllocateBuffer() and + FreeBuffer() to return EFI_UNSUPPORTED. It is useful to save code size if a platform have only + ISA device to do slave DMA R/W transfer. This flag is only effective when PcdIsaBusSupportDma + is set to TRUE. If PcdIsaBusSupportDma is set to FALSE, Map() and UnMap() will simply + return EFI_UNSUPPORTED. Please check description for PcdIsaBusSupportDma for details.</HelpText>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea>
\ No newline at end of file diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaIo.c b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaIo.c new file mode 100644 index 0000000000..1a3497dfda --- /dev/null +++ b/IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaIo.c @@ -0,0 +1,1646 @@ +/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ IsaIo.c
+
+Abstract:
+
+ The implementation for EFI_ISA_IO_PROTOCOL.
+
+--*/
+
+//
+// Include common header file for this module.
+//
+#include "InternalIsaIo.h"
+
+#include <IndustryStandard/Pcat.h>
+
+//
+// Driver Support Global Variables
+//
+EFI_ISA_IO_PROTOCOL IsaIoInterface = {
+ {
+ IsaIoMemRead,
+ IsaIoMemWrite
+ },
+ {
+ IsaIoIoRead,
+ IsaIoIoWrite
+ },
+ IsaIoCopyMem,
+ IsaIoMap,
+ IsaIoUnmap,
+ IsaIoAllocateBuffer,
+ IsaIoFreeBuffer,
+ IsaIoFlush,
+ NULL,
+ 0,
+ NULL
+};
+
+static EFI_ISA_DMA_REGISTERS DmaRegisters[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
+ },
+};
+
+EFI_STATUS
+ReportErrorStatusCode (
+ EFI_STATUS_CODE_VALUE Code
+ )
+/*++
+
+Routine Description:
+
+ report a error Status code of PCI bus driver controller
+
+Arguments:
+
+ Code - The error status code.
+
+Returns:
+
+ EFI_SUCCESS - Success to report status code.
+
+
+--*/
+{
+ return REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ Code
+ );
+}
+
+//
+// Driver Support Functions
+//
+
+EFI_STATUS
+InitializeIsaIoInstance (
+ IN ISA_IO_DEVICE *IsaIoDevice,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *IsaDeviceResourceList
+ )
+/*++
+
+Routine Description:
+
+ Initializes an ISA I/O Instance
+
+Arguments:
+
+ IsaIoDevice - The iso device to be initialized.
+ IsaDeviceResourceList - The resource list.
+
+Returns:
+
+ EFI_SUCCESS - Initial success.
+
+--*/
+{
+ //
+ // Initializes an ISA I/O Instance
+ //
+ CopyMem (
+ &IsaIoDevice->IsaIo,
+ &IsaIoInterface,
+ sizeof (EFI_ISA_IO_PROTOCOL)
+ );
+
+ IsaIoDevice->IsaIo.ResourceList = IsaDeviceResourceList;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoIoRead (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs an ISA I/O Read Cycle
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Width - Signifies the width of the I/O operation.
+ Offset - The offset in ISA I/O space to start the I/O operation.
+ Count - The number of I/O operations to perform.
+ Buffer - The destination buffer to store the results
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the device sucessfully.
+ EFI_UNSUPPORTED - The Offset is not valid for this device.
+ EFI_INVALID_PARAMETER - Width or Count, or both, were invalid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ 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;
+ }
+ //
+ // Call PciIo->Io.Read
+ //
+ 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)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoIoWrite (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs an ISA I/O Write Cycle
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Width - Signifies the width of the I/O operation.
+ Offset - The offset in ISA I/O space to start the I/O operation.
+ Count - The number of I/O operations to perform.
+ Buffer - The source buffer to write data from
+
+Returns:
+
+ EFI_SUCCESS - The data was writen to the device sucessfully.
+ EFI_UNSUPPORTED - The Offset is not valid for this device.
+ EFI_INVALID_PARAMETER - Width or Count, or both, were invalid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ 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;
+ }
+ //
+ // Call PciIo->Io.Write
+ //
+ 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)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+WritePort (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINT32 Offset,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Writes an 8 bit I/O Port
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Offset - The offset in ISA IO space to start the IO operation.
+ Value - The data to write port.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Parameter is invalid.
+ EFI_UNSUPPORTED - The address range specified by Offset is not valid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+
+ IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);
+
+ //
+ // Call PciIo->Io.Write
+ //
+ Status = IsaIoDevice->PciIo->Io.Write (
+ IsaIoDevice->PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Offset,
+ 1,
+ &Value
+ );
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ return Status;
+ }
+
+ gBS->Stall (50);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteDmaPort (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINT32 AddrOffset,
+ IN UINT32 PageOffset,
+ IN UINT32 CountOffset,
+ IN UINT32 BaseAddress,
+ IN UINT16 Count
+ )
+/*++
+
+Routine Description:
+
+ Writes I/O operation base address and count number to a 8 bit I/O Port.
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ AddrOffset - The address' offset.
+ PageOffset - The page's offest.
+ CountOffset - The count's offset.
+ BaseAddress - The base address.
+ Count - The number of I/O operations to perform.
+
+Returns:
+
+ EFI_SUCCESS - Success.
+ EFI_INVALID_PARAMETER - Parameter is invalid.
+ EFI_UNSUPPORTED - The address range specified by these Offsets and Count is not valid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ 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));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoUnmap (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+/*++
+
+Routine Description:
+
+ Unmaps a memory region for DMA
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Mapping - The mapping value returned from EFI_ISA_IO.Map().
+
+Returns:
+
+ EFI_SUCCESS - The range was unmapped.
+ EFI_DEVICE_ERROR - The data was not committed to the target system memory.
+
+--*/
+{
+ ISA_MAP_INFO *IsaMapInfo;
+
+ //
+ // Unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA.
+ //
+ if (!FeaturePcdGet (PcdIsaBusSupportDma)) {
+ 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);
+ gBS->FreePool (IsaMapInfo);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoFlush (
+ IN EFI_ISA_IO_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ Flushes a DMA buffer
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+
+Returns:
+
+ EFI_SUCCESS - The buffers were flushed.
+ EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+
+ IsaIoDevice = ISA_IO_DEVICE_FROM_ISA_IO_THIS (This);
+
+ //
+ // Call PciIo->Flush
+ //
+ Status = IsaIoDevice->PciIo->Flush (IsaIoDevice->PciIo);
+
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+IsaIoVerifyAccess (
+ IN ISA_IO_DEVICE *IsaIoDevice,
+ IN ISA_ACCESS_TYPE Type,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN OUT UINT32 *Offset
+ )
+/*++
+
+Routine Description:
+
+ Verifies access to an ISA device
+
+Arguments:
+
+ IsaIoDevice - The ISA device to be verified.
+ Type - The Access type. The input must be either IsaAccessTypeMem or IsaAccessTypeIo.
+ Width - Signifies the width of the memory operation.
+ Count - The number of memory operations to perform.
+ Offset - The offset in ISA memory space to start the memory operation.
+
+Returns:
+
+ EFI_SUCCESS - Verify success.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_UNSUPPORTED - The device ont support the access type.
+
+--*/
+{
+ 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;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoMemRead (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs an ISA Memory Read Cycle
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Width - Signifies the width of the memory operation.
+ Offset - The offset in ISA memory space to start the memory operation.
+ Count - The number of memory operations to perform.
+ Buffer - The destination buffer to store the results
+
+Returns:
+
+ EFI_SUCCESS - The data was read from the device successfully.
+ EFI_UNSUPPORTED - The Offset is not valid for this device.
+ EFI_INVALID_PARAMETER - Width or Count, or both, were invalid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+
+ //
+ // Set Feature Flag PcdIsaBusSupportBusMaster to FALSE to disable support for
+ // ISA Bus Master.
+ //
+ // So we just return EFI_UNSUPPORTED for these functions.
+ //
+ if (!FeaturePcdGet (PcdIsaBusSupportIsaMemory)) {
+ 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;
+ }
+ //
+ // Call PciIo->Mem.Read
+ //
+ 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)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoMemWrite (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Performs an ISA Memory Write Cycle
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Width - Signifies the width of the memory operation.
+ Offset - The offset in ISA memory space to start the memory operation.
+ Count - The number of memory operations to perform.
+ Buffer - The source buffer to write data from
+
+Returns:
+
+ EFI_SUCCESS - The data was written to the device sucessfully.
+ EFI_UNSUPPORTED - The Offset is not valid for this device.
+ EFI_INVALID_PARAMETER - Width or Count, or both, were invalid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+
+ //
+ // Set Feature Flag PcdIsaBusSupportBusMaster to FALSE to disable support for
+ // ISA Bus Master.
+ //
+ // So we just return EFI_UNSUPPORTED for these functions.
+ //
+ if (!FeaturePcdGet (PcdIsaBusSupportIsaMemory)) {
+ 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;
+ }
+ //
+ // Call PciIo->Mem.Write
+ //
+ 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)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+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
+ )
+/*++
+
+Routine Description:
+
+ Performs an ISA I/O Copy Memory
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Width - Signifies the width of the memory copy operation.
+ DestOffset - The offset of the destination
+ SrcOffset - The offset of the source
+ Count - The number of memory copy operations to perform
+
+Returns:
+
+ EFI_SUCCESS - The data was copied sucessfully.
+ EFI_UNSUPPORTED - The DestOffset or SrcOffset is not valid for this device.
+ EFI_INVALID_PARAMETER - Width or Count, or both, were invalid.
+ EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources.
+
+--*/
+{
+ EFI_STATUS Status;
+ ISA_IO_DEVICE *IsaIoDevice;
+
+ //
+ // Set Feature Flag PcdIsaBusSupportBusMaster to FALSE to disable support for
+ // ISA Bus Master.
+ //
+ // So we just return EFI_UNSUPPORTED for these functions.
+ //
+ if (!FeaturePcdGet (PcdIsaBusSupportIsaMemory)) {
+ 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;
+ }
+ //
+ // Call PciIo->CopyMem
+ //
+ 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)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+IsaIoMap_OnlySupportSlaveReadWrite (
+ 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
+ )
+/*++
+
+Routine Description:
+
+ Maps a memory region for DMA, note this implementation
+ only supports slave read/write operation to save code size.
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Operation - Indicates the type of DMA (slave or bus master), and if
+ the DMA operation is going to read or write to system memory.
+ 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.
+ ChannelAttributes - The attributes of the DMA channel to use for this DMA operation
+ HostAddress - The system memory address to map to the device.
+ NumberOfBytes - On input the number of bytes to map. On output the number
+ of bytes that were mapped.
+ DeviceAddress - The resulting map address for the bus master device to use
+ to access the hosts HostAddress.
+ Mapping - A resulting value to pass to EFI_ISA_IO.Unmap().
+
+Returns:
+
+ EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
+ EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
+ EFI_UNSUPPORTED - The HostAddress can not be mapped as a common buffer.
+ EFI_DEVICE_ERROR - The system hardware could not map the requested address.
+ EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
+
+--*/
+{
+ 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) > ISA_MAX_MEMORY_ADDRESS) {
+ //
+ // 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 = ISA_MAX_MEMORY_ADDRESS - 1;
+
+ //
+ // Allocate a buffer below 16MB to map the transfer to.
+ //
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ IsaMapInfo->NumberOfPages,
+ &IsaMapInfo->MappedHostAddress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->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,
+ DmaRegisters[ChannelNumber].Address,
+ DmaRegisters[ChannelNumber].Page,
+ DmaRegisters[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;
+}
+
+STATIC
+EFI_STATUS
+IsaIoMap_FullSupport (
+ 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
+ )
+/*++
+
+Routine Description:
+
+ Maps a memory region for DMA. This implementation implement the
+ the full mapping support.
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Operation - Indicates the type of DMA (slave or bus master), and if
+ the DMA operation is going to read or write to system memory.
+ 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.
+ ChannelAttributes - The attributes of the DMA channel to use for this DMA operation
+ HostAddress - The system memory address to map to the device.
+ NumberOfBytes - On input the number of bytes to map. On output the number
+ of bytes that were mapped.
+ DeviceAddress - The resulting map address for the bus master device to use
+ - to access the hosts HostAddress.
+ Mapping - A resulting value to pass to EFI_ISA_IO.Unmap().
+
+Returns:
+
+ EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
+ EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
+ EFI_UNSUPPORTED - The HostAddress can not be mapped as a common buffer.
+ EFI_DEVICE_ERROR - The system hardware could not map the requested address.
+ EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
+
+--*/
+{
+ 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;
+ }
+ //
+ // 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)) {
+ 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
+ )
+ ) {
+ 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) ||
+ (ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16)
+ ) {
+ 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) ||
+ (!(ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16))
+ ) {
+ 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) {
+ if (ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if (!(ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+ //
+ // Map the HostAddress to a DeviceAddress.
+ //
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+ if ((PhysicalAddress +*NumberOfBytes) > ISA_MAX_MEMORY_ADDRESS) {
+ //
+ // 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 = ISA_MAX_MEMORY_ADDRESS - 1;
+
+ //
+ // Allocate a buffer below 16MB to map the transfer to.
+ //
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ IsaMapInfo->NumberOfPages,
+ &IsaMapInfo->MappedHostAddress
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->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) {
+ DmaMode |= B_8237_DMA_CHMODE_AE;
+ }
+
+ if (ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE) {
+ DmaMode |= V_8237_DMA_CHMODE_DEMAND;
+ }
+
+ if (ChannelAttributes & EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE) {
+ 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,
+ DmaRegisters[ChannelNumber].Address,
+ DmaRegisters[ChannelNumber].Page,
+ DmaRegisters[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;
+}
+
+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
+ )
+/*++
+
+Routine Description:
+
+ Maps a memory region for DMA
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Operation - Indicates the type of DMA (slave or bus master), and if
+ the DMA operation is going to read or write to system memory.
+ 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.
+ ChannelAttributes - The attributes of the DMA channel to use for this DMA operation
+ HostAddress - The system memory address to map to the device.
+ NumberOfBytes - On input the number of bytes to map. On output the number
+ of bytes that were mapped.
+ DeviceAddress - The resulting map address for the bus master device to use
+ - to access the hosts HostAddress.
+ Mapping - A resulting value to pass to EFI_ISA_IO.Unmap().
+
+Returns:
+
+ EFI_SUCCESS - The range was mapped for the returned NumberOfBytes.
+ EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined.
+ EFI_UNSUPPORTED - The HostAddress can not be mapped as a common buffer.
+ EFI_DEVICE_ERROR - The system hardware could not map the requested address.
+ EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
+
+--*/
+{
+ //
+ // Or unset Feature Flag PcdIsaBusSupportDma to disable support for ISA DMA.
+ //
+ if (!FeaturePcdGet (PcdIsaBusSupportDma)) {
+ 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 (FeaturePcdGet (PcdIsaBusOnlySupportSlaveDma)) {
+ return IsaIoMap_OnlySupportSlaveReadWrite (
+ This,
+ Operation,
+ ChannelNumber,
+ ChannelAttributes,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+
+ } else {
+ return IsaIoMap_FullSupport (
+ This,
+ Operation,
+ ChannelNumber,
+ ChannelAttributes,
+ HostAddress,
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping
+ );
+ }
+}
+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
+ )
+/*++
+
+Routine Description:
+
+ Allocates a common buffer for DMA
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Type - The type allocation to perform.
+ MemoryType - The type of memory to allocate.
+ Pages - The number of pages to allocate.
+ HostAddress - A pointer to store the base address of the allocated range.
+ Attributes - The requested bit mask of attributes for the allocated range.
+
+Returns:
+
+ EFI_SUCCESS - The requested memory pages were allocated.
+ EFI_INVALID_PARAMETER - Type is invalid or MemoryType is invalid or HostAddress is NULL
+ EFI_UNSUPPORTED - Attributes is unsupported or the memory range specified
+ by HostAddress, Pages, and Type is not available for common buffer use.
+ EFI_OUT_OF_RESOURCES - The memory pages could not be allocated.
+
+--*/
+{
+ 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 (!FeaturePcdGet (PcdIsaBusSupportDma) || FeaturePcdGet (PcdIsaBusOnlySupportSlaveDma)) {
+ 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)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (ISA_MAX_MEMORY_ADDRESS - 1);
+ if (Type == AllocateAddress) {
+ if ((UINTN) (*HostAddress) >= ISA_MAX_MEMORY_ADDRESS) {
+ return EFI_UNSUPPORTED;
+ } else {
+ PhysicalAddress = (UINTN) (*HostAddress);
+ }
+ }
+
+ if (Type == AllocateAnyPages) {
+ Type = AllocateMaxAddress;
+ }
+
+ Status = gBS->AllocatePages (Type, MemoryType, Pages, &PhysicalAddress);
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ return Status;
+ }
+
+ *HostAddress = (VOID *) (UINTN) PhysicalAddress;
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IsaIoFreeBuffer (
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+/*++
+
+Routine Description:
+
+ Frees a common buffer
+
+Arguments:
+
+ This - A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ Pages - The number of pages to free.
+ HostAddress - The base address of the allocated range.
+
+Returns:
+
+ EFI_SUCCESS - The requested memory pages were freed.
+ EFI_INVALID_PARAMETER - The memory was not allocated with EFI_ISA_IO.AllocateBufer().
+
+--*/
+{
+ 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 (!FeaturePcdGet (PcdIsaBusSupportDma) || FeaturePcdGet (PcdIsaBusOnlySupportSlaveDma)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ PhysicalAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+ Status = gBS->FreePages (
+ PhysicalAddress,
+ Pages
+ );
+ if (EFI_ERROR (Status)) {
+ ReportErrorStatusCode (EFI_IO_BUS_LPC | EFI_IOB_EC_CONTROLLER_ERROR);
+ }
+
+ return Status;
+}
+
|