add native ide/ahci driver

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10901 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
erictian 2010-09-29 05:50:45 +00:00
parent 22c5a7af03
commit a41b5272cd
8 changed files with 8805 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,464 @@
/** @file
Header file for AHCI mode of ATA host 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.
**/
#ifndef __ATA_HC_AHCI_MODE_H__
#define __ATA_HC_AHCI_MODE_H__
#define EFI_AHCI_BAR_INDEX 0x05
#define EFI_AHCI_CAPABILITY_OFFSET 0x0000
#define EFI_AHCI_GHC_OFFSET 0x0004
#define EFI_AHCI_GHC_RESET BIT0
#define EFI_AHCI_GHC_IE BIT1
#define EFI_AHCI_GHC_ENABLE BIT31
#define EFI_AHCI_IS_OFFSET 0x0008
#define EFI_AHCI_PI_OFFSET 0x000C
typedef struct {
UINT32 Lower32;
UINT32 Upper32;
} DATA_32;
typedef union {
DATA_32 Uint32;
UINT64 Uint64;
} DATA_64;
#define EFI_AHCI_ATAPI_DEVICE_SIG 0xEB140000
#define EFI_AHCI_ATA_DEVICE_SIG 0x00000000
#define EFI_AHCI_PORT_MULTIPLIER_SIG 0x96690000
#define EFI_AHCI_ATAPI_SIG_MASK 0xFFFF0000
//
// Each PRDT entry can point to a memory block up to 4M byte
//
#define EFI_AHCI_MAX_DATA_PER_PRDT 0x400000
#define EFI_AHCI_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device
#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20
#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FIS - Device to Host
#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20
#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activate FIS - Device to Host
#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4
#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup FIS - Bi-directional
#define EFI_AHCI_FIS_DMA_SETUP_LENGTH 28
#define EFI_AHCI_FIS_DATA 0x46 //Data FIS - Bi-directional
#define EFI_AHCI_FIS_BIST 0x58 //BIST Activate FIS - Bi-directional
#define EFI_AHCI_FIS_BIST_LENGTH 12
#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS - Device to Host
#define EFI_AHCI_FIS_PIO_SETUP_LENGTH 20
#define EFI_AHCI_FIS_SET_DEVICE 0xA1 //Set Device Bits FIS - Device to Host
#define EFI_AHCI_FIS_SET_DEVICE_LENGTH 8
#define EFI_AHCI_D2H_FIS_OFFSET 0x40
#define EFI_AHCI_DMA_FIS_OFFSET 0x00
#define EFI_AHCI_PIO_FIS_OFFSET 0x20
#define EFI_AHCI_SDB_FIS_OFFSET 0x58
#define EFI_AHCI_FIS_TYPE_MASK 0xFF
#define EFI_AHCI_U_FIS_OFFSET 0x60
//
// Port register
//
#define EFI_AHCI_PORT_START 0x0100
#define EFI_AHCI_PORT_REG_WIDTH 0x0080
#define EFI_AHCI_PORT_CLB 0x0000
#define EFI_AHCI_PORT_CLBU 0x0004
#define EFI_AHCI_PORT_FB 0x0008
#define EFI_AHCI_PORT_FBU 0x000C
#define EFI_AHCI_PORT_IS 0x0010
#define EFI_AHCI_PORT_IS_DHRS BIT0
#define EFI_AHCI_PORT_IS_PSS BIT1
#define EFI_AHCI_PORT_IS_SSS BIT2
#define EFI_AHCI_PORT_IS_SDBS BIT3
#define EFI_AHCI_PORT_IS_UFS BIT4
#define EFI_AHCI_PORT_IS_DPS BIT5
#define EFI_AHCI_PORT_IS_PCS BIT6
#define EFI_AHCI_PORT_IS_DIS BIT7
#define EFI_AHCI_PORT_IS_PRCS BIT22
#define EFI_AHCI_PORT_IS_IPMS BIT23
#define EFI_AHCI_PORT_IS_OFS BIT24
#define EFI_AHCI_PORT_IS_INFS BIT26
#define EFI_AHCI_PORT_IS_IFS BIT27
#define EFI_AHCI_PORT_IS_HBDS BIT28
#define EFI_AHCI_PORT_IS_HBFS BIT29
#define EFI_AHCI_PORT_IS_TFES BIT30
#define EFI_AHCI_PORT_IS_CPDS BIT31
#define EFI_AHCI_PORT_IS_CLEAR 0xFFFFFFFF
#define EFI_AHCI_PORT_IS_FIS_CLEAR 0x0000000F
#define EFI_AHCI_PORT_IE 0x0014
#define EFI_AHCI_PORT_CMD 0x0018
#define EFI_AHCI_PORT_CMD_ST_MASK 0xFFFFFFFE
#define EFI_AHCI_PORT_CMD_ST BIT0
#define EFI_AHCI_PORT_CMD_SUD BIT1
#define EFI_AHCI_PORT_CMD_POD BIT2
#define EFI_AHCI_PORT_CMD_COL BIT3
#define EFI_AHCI_PORT_CMD_CR BIT15
#define EFI_AHCI_PORT_CMD_FRE BIT4
#define EFI_AHCI_PORT_CMD_FR BIT14
#define EFI_AHCI_PORT_CMD_MASK ~(EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_FRE | EFI_AHCI_PORT_CMD_COL)
#define EFI_AHCI_PORT_CMD_PMA BIT17
#define EFI_AHCI_PORT_CMD_HPCP BIT18
#define EFI_AHCI_PORT_CMD_MPSP BIT19
#define EFI_AHCI_PORT_CMD_CPD BIT20
#define EFI_AHCI_PORT_CMD_ESP BIT21
#define EFI_AHCI_PORT_CMD_ATAPI BIT24
#define EFI_AHCI_PORT_CMD_DLAE BIT25
#define EFI_AHCI_PORT_CMD_ALPE BIT26
#define EFI_AHCI_PORT_CMD_ASP BIT27
#define EFI_AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | BIT31)
#define EFI_AHCI_PORT_CMD_ACTIVE (1 << 28 )
#define EFI_AHCI_PORT_TFD 0x0020
#define EFI_AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0)
#define EFI_AHCI_PORT_TFD_BSY BIT7
#define EFI_AHCI_PORT_TFD_DRQ BIT3
#define EFI_AHCI_PORT_TFD_ERR BIT0
#define EFI_AHCI_PORT_TFD_ERR_MASK 0x00FF00
#define EFI_AHCI_PORT_SIG 0x0024
#define EFI_AHCI_PORT_SSTS 0x0028
#define EFI_AHCI_PORT_SSTS_DET_MASK 0x000F
#define EFI_AHCI_PORT_SSTS_DET 0x0001
#define EFI_AHCI_PORT_SSTS_DET_PCE 0x0003
#define EFI_AHCI_PORT_SSTS_SPD_MASK 0x00F0
#define EFI_AHCI_PORT_SCTL 0x002C
#define EFI_AHCI_PORT_SCTL_DET_MASK 0x000F
#define EFI_AHCI_PORT_SCTL_MASK (~EFI_AHCI_PORT_SCTL_DET_MASK)
#define EFI_AHCI_PORT_SCTL_DET_INIT 0x0001
#define EFI_AHCI_PORT_SCTL_DET_PHYCOMM 0x0003
#define EFI_AHCI_PORT_SCTL_SPD_MASK 0x00F0
#define EFI_AHCI_PORT_SCTL_IPM_MASK 0x0F00
#define EFI_AHCI_PORT_SCTL_IPM_INIT 0x0300
#define EFI_AHCI_PORT_SCTL_IPM_PSD 0x0100
#define EFI_AHCI_PORT_SCTL_IPM_SSD 0x0200
#define EFI_AHCI_PORT_SERR 0x0030
#define EFI_AHCI_PORT_SERR_RDIE BIT0
#define EFI_AHCI_PORT_SERR_RCE BIT1
#define EFI_AHCI_PORT_SERR_TDIE BIT8
#define EFI_AHCI_PORT_SERR_PCDIE BIT9
#define EFI_AHCI_PORT_SERR_PE BIT10
#define EFI_AHCI_PORT_SERR_IE BIT11
#define EFI_AHCI_PORT_SERR_PRC BIT16
#define EFI_AHCI_PORT_SERR_PIE BIT17
#define EFI_AHCI_PORT_SERR_CW BIT18
#define EFI_AHCI_PORT_SERR_BDE BIT19
#define EFI_AHCI_PORT_SERR_DE BIT20
#define EFI_AHCI_PORT_SERR_CRCE BIT21
#define EFI_AHCI_PORT_SERR_HE BIT22
#define EFI_AHCI_PORT_SERR_LSE BIT23
#define EFI_AHCI_PORT_SERR_TSTE BIT24
#define EFI_AHCI_PORT_SERR_UFT BIT25
#define EFI_AHCI_PORT_SERR_EX BIT26
#define EFI_AHCI_PORT_ERR_CLEAR 0xFFFFFFFF
#define EFI_AHCI_PORT_SACT 0x0034
#define EFI_AHCI_PORT_CI 0x0038
#define EFI_AHCI_PORT_SNTF 0x003C
#pragma pack(1)
//
// Command List structure includes total 32 entries.
// The entry data structure is listed at the following.
//
typedef struct {
UINT32 AhciCmdCfl:5; //Command FIS Length
UINT32 AhciCmdA:1; //ATAPI
UINT32 AhciCmdW:1; //Write
UINT32 AhciCmdP:1; //Prefetchable
UINT32 AhciCmdR:1; //Reset
UINT32 AhciCmdB:1; //BIST
UINT32 AhciCmdC:1; //Clear Busy upon R_OK
UINT32 AhciCmdRsvd:1;
UINT32 AhciCmdPmp:4; //Port Multiplier Port
UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length
UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count
UINT32 AhciCmdCtba; //Command Table Descriptor Base Address
UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address Upper 32-BITs
UINT32 AhciCmdRsvd1[4];
} EFI_AHCI_COMMAND_LIST;
//
// This is a software constructed FIS.
// For data transfer operations, this is the H2D Register FIS format as
// specified in the Serial ATA Revision 2.6 specification.
//
typedef struct {
UINT8 AhciCFisType;
UINT8 AhciCFisPmNum:4;
UINT8 AhciCFisRsvd:1;
UINT8 AhciCFisRsvd1:1;
UINT8 AhciCFisRsvd2:1;
UINT8 AhciCFisCmdInd:1;
UINT8 AhciCFisCmd;
UINT8 AhciCFisFeature;
UINT8 AhciCFisSecNum;
UINT8 AhciCFisClyLow;
UINT8 AhciCFisClyHigh;
UINT8 AhciCFisDevHead;
UINT8 AhciCFisSecNumExp;
UINT8 AhciCFisClyLowExp;
UINT8 AhciCFisClyHighExp;
UINT8 AhciCFisFeatureExp;
UINT8 AhciCFisSecCount;
UINT8 AhciCFisSecCountExp;
UINT8 AhciCFisRsvd3;
UINT8 AhciCFisControl;
UINT8 AhciCFisRsvd4[4];
UINT8 AhciCFisRsvd5[44];
} EFI_AHCI_COMMAND_FIS;
//
// ACMD: ATAPI command (12 or 16 bytes)
//
typedef struct {
UINT8 AtapiCmd[0x10];
} EFI_AHCI_ATAPI_COMMAND;
//
// Physical Region Descriptor Table includes up to 65535 entries
// The entry data structure is listed at the following.
// the actual entry number comes from the PRDTL field in the command
// list entry for this command slot.
//
typedef struct {
UINT32 AhciPrdtDba; //Data Base Address
UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs
UINT32 AhciPrdtRsvd;
UINT32 AhciPrdtDbc:22; //Data Byte Count
UINT32 AhciPrdtRsvd1:9;
UINT32 AhciPrdtIoc:1; //Interrupt on Completion
} EFI_AHCI_COMMAND_PRDT;
//
// Command table data strucute which is pointed to by the entry in the command list
//
typedef struct {
EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed FIS.
EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI cmd.
UINT8 Reserved[0x30];
EFI_AHCI_COMMAND_PRDT PrdtTable[65535]; // The scatter/gather list for data transfer
} EFI_AHCI_COMMAND_TABLE;
//
// Received FIS structure
//
typedef struct {
UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00
UINT8 AhciDmaSetupFisRsvd[0x04];
UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20
UINT8 AhciPioSetupFisRsvd[0x0C];
UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x40
UINT8 AhciD2HRegisterFisRsvd[0x04];
UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset 0x58
UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60
UINT8 AhciUnknownFisRsvd[0x60];
} EFI_AHCI_RECEIVED_FIS;
#pragma pack()
typedef struct {
EFI_AHCI_RECEIVED_FIS *AhciRFis;
EFI_AHCI_COMMAND_LIST *AhciCmdList;
EFI_AHCI_COMMAND_TABLE *AhciCommandTable;
EFI_AHCI_RECEIVED_FIS *AhciRFisPciAddr;
EFI_AHCI_COMMAND_LIST *AhciCmdListPciAddr;
EFI_AHCI_COMMAND_TABLE *AhciCommandTablePciAddr;
UINT64 MaxCommandListSize;
UINT64 MaxCommandTableSize;
UINT64 MaxReceiveFisSize;
VOID *MapRFis;
VOID *MapCmdList;
VOID *MapCommandTable;
} EFI_AHCI_REGISTERS;
/**
This function is used to send out ATAPI commands conforms to the Packet Command
with PIO Protocol.
@param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port.
@param PortMultiplier The number of port multiplier.
@param Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET structure.
@retval EFI_SUCCESS send out the ATAPI packet command successfully
and device sends data successfully.
@retval EFI_DEVICE_ERROR the device failed to send data.
**/
EFI_STATUS
EFIAPI
AhciPacketCommandExecute (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port,
IN UINT8 PortMultiplier,
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
);
/**
Start command for give slot on specific port.
@param PciIo The PCI IO protocol instance.
@param Port The number of port.
@param CommandSlot The number of CommandSlot.
@param Timeout The timeout value of start.
@retval EFI_DEVICE_ERROR The command start unsuccessfully.
@retval EFI_TIMEOUT The operation is time out.
@retval EFI_SUCCESS The command start successfully.
**/
EFI_STATUS
EFIAPI
AhciStartCommand (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT8 CommandSlot,
IN UINT64 Timeout
);
/**
Stop command running for giving port
@param PciIo The PCI IO protocol instance.
@param Port The number of port.
@param Timeout The timeout value of stop.
@retval EFI_DEVICE_ERROR The command stop unsuccessfully.
@retval EFI_TIMEOUT The operation is time out.
@retval EFI_SUCCESS The command stop successfully.
**/
EFI_STATUS
EFIAPI
AhciStopCommand (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT8 Port,
IN UINT64 Timeout
);
/**
Start a non data transfer on specific port.
@param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port.
@param PortMultiplier The timeout value of stop.
@param AtapiCommand The atapi command will be used for the transfer.
@param AtapiCommandLength The length of the atapi command.
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
@param Timeout The timeout value of non data transfer.
@retval EFI_DEVICE_ERROR The non data transfer abort with error occurs.
@retval EFI_TIMEOUT The operation is time out.
@retval EFI_UNSUPPORTED The device is not ready for transfer.
@retval EFI_SUCCESS The non data transfer executes successfully.
**/
EFI_STATUS
EFIAPI
AhciNonDataTransfer (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port,
IN UINT8 PortMultiplier,
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
IN UINT8 AtapiCommandLength,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN UINT64 Timeout
);
/**
Start a DMA data transfer on specific port
@param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port.
@param PortMultiplier The timeout value of stop.
@param AtapiCommand The atapi command will be used for the transfer.
@param AtapiCommandLength The length of the atapi command.
@param Read The transfer direction.
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
@param MemoryAddr The pointer to the data buffer.
@param DataCount The data count to be transferred.
@param Timeout The timeout value of non data transfer.
@retval EFI_DEVICE_ERROR The DMA data transfer abort with error occurs.
@retval EFI_TIMEOUT The operation is time out.
@retval EFI_UNSUPPORTED The device is not ready for transfer.
@retval EFI_SUCCESS The DMA data transfer executes successfully.
**/
EFI_STATUS
EFIAPI
AhciDmaTransfer (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port,
IN UINT8 PortMultiplier,
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
IN UINT8 AtapiCommandLength,
IN BOOLEAN Read,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN OUT VOID *MemoryAddr,
IN UINTN DataCount,
IN UINT64 Timeout
);
/**
Start a PIO data transfer on specific port.
@param PciIo The PCI IO protocol instance.
@param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.
@param Port The number of port.
@param PortMultiplier The timeout value of stop.
@param AtapiCommand The atapi command will be used for the transfer.
@param AtapiCommandLength The length of the atapi command.
@param Read The transfer direction.
@param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK data.
@param AtaStatusBlock The EFI_ATA_STATUS_BLOCK data.
@param MemoryAddr The pointer to the data buffer.
@param DataCount The data count to be transferred.
@param Timeout The timeout value of non data transfer.
@retval EFI_DEVICE_ERROR The PIO data transfer abort with error occurs.
@retval EFI_TIMEOUT The operation is time out.
@retval EFI_UNSUPPORTED The device is not ready for transfer.
@retval EFI_SUCCESS The PIO data transfer executes successfully.
**/
EFI_STATUS
EFIAPI
AhciPioTransfer (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_AHCI_REGISTERS *AhciRegisters,
IN UINT8 Port,
IN UINT8 PortMultiplier,
IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,
IN UINT8 AtapiCommandLength,
IN BOOLEAN Read,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN OUT VOID *MemoryAddr,
IN UINT32 DataCount,
IN UINT64 Timeout
);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
## @file
# AtaAtapiPassThru driver to provide native IDE/AHCI mode support.
#
# This driver installs AtaPassThru and ExtScsiPassThru protocol in each ide/sata controller
# to access to all attached Ata/Atapi devices.
#
# 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 = AtaAtapiPassThruDxe
FILE_GUID = 5E523CB4-D397-4986-87BD-A6DD8B22F455
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeAtaAtapiPassThru
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gAtaAtapiPassThruDriverBinding
# COMPONENT_NAME = gAtaAtapiPassThruComponentName
# COMPONENT_NAME2 = gAtaAtapiPassThruComponentName2
#
#
[Sources]
AtaAtapiPassThru.c
AtaAtapiPassThru.h
AhciMode.c
AhciMode.h
IdeMode.c
IdeMode.h
ComponentName.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
DevicePathLib
UefiBootServicesTableLib
MemoryAllocationLib
BaseMemoryLib
UefiLib
BaseLib
UefiDriverEntryPoint
DebugLib
TimerLib
[Guids]
[Protocols]
gEfiIdeControllerInitProtocolGuid # BY_START
gEfiAtaPassThruProtocolGuid # BY_START
gEfiExtScsiPassThruProtocolGuid # BY_START
gEfiDevicePathProtocolGuid # TO_START
gEfiPciIoProtocolGuid # TO_START

View File

@ -0,0 +1,251 @@
/** @file
UEFI Component Name(2) protocol implementation for AtaAtapiPassThru 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 "AtaAtapiPassThru.h"
//
// Driver name table
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mAtaAtapiPassThruDriverNameTable[] = {
{ "eng;en", L"AtaAtapiPassThru Driver" },
{ NULL , NULL }
};
//
// Controller name table
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mAtaAtapiPassThruIdeControllerNameTable[] = {
{ "eng;en", L"IDE Controller" },
{ NULL , NULL }
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mAtaAtapiPassThruAhciControllerNameTable[] = {
{ "eng;en", L"AHCI Controller" },
{ NULL , NULL }
};
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gAtaAtapiPassThruComponentName = {
AtaAtapiPassThruComponentNameGetDriverName,
AtaAtapiPassThruComponentNameGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gAtaAtapiPassThruComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) AtaAtapiPassThruComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) AtaAtapiPassThruComponentNameGetControllerName,
"en"
};
/**
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
AtaAtapiPassThruComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mAtaAtapiPassThruDriverNameTable,
DriverName,
(BOOLEAN)(This == &gAtaAtapiPassThruComponentName)
);
}
/**
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
AtaAtapiPassThruComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
VOID *Interface;
ATA_ATAPI_PASS_THRU_INSTANCE *Instance;
if (Language == NULL || ControllerName == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// This is a device driver, so ChildHandle must be NULL.
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing Controller Handle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gAtaAtapiPassThruDriverBinding.DriverBindingHandle,
&gEfiIdeControllerInitProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// AtaPassThru and ExtScsiPassThru should also be installed at the controller handle.
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiAtaPassThruProtocolGuid,
&Interface,
gAtaAtapiPassThruDriverBinding.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (Interface);
if (Instance->Mode == EfiAtaIdeMode) {
ControllerNameTable = mAtaAtapiPassThruIdeControllerNameTable;
} else if (Instance->Mode == EfiAtaAhciMode) {
ControllerNameTable = mAtaAtapiPassThruAhciControllerNameTable;
} else {
return EFI_UNSUPPORTED;
}
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gAtaAtapiPassThruComponentName)
);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,293 @@
/** @file
Header file for IDE mode of ATA host 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.
**/
#ifndef __ATA_HC_IDE_MODE_H__
#define __ATA_HC_IDE_MODE_H__
typedef enum {
EfiIdePrimary = 0,
EfiIdeSecondary = 1,
EfiIdeMaxChannel = 2
} EFI_IDE_CHANNEL;
typedef enum {
EfiIdeMaster = 0,
EfiIdeSlave = 1,
EfiIdeMaxDevice = 2
} EFI_IDE_DEVICE;
///
/// PIO mode definition
///
typedef enum {
EfiAtaPioModeBelow2,
EfiAtaPioMode2,
EfiAtaPioMode3,
EfiAtaPioMode4
} EFI_ATA_PIO_MODE;
//
// Multi word DMA definition
//
typedef enum {
EfiAtaMdmaMode0,
EfiAtaMdmaMode1,
EfiAtaMdmaMode2
} EFI_ATA_MDMA_MODE;
//
// UDMA mode definition
//
typedef enum {
EfiAtaUdmaMode0,
EfiAtaUdmaMode1,
EfiAtaUdmaMode2,
EfiAtaUdmaMode3,
EfiAtaUdmaMode4,
EfiAtaUdmaMode5
} EFI_ATA_UDMA_MODE;
//
// Bus Master Reg
//
#define BMIC_NREAD BIT3
#define BMIC_START BIT0
#define BMIS_INTERRUPT BIT2
#define BMIS_ERROR BIT1
#define BMIC_OFFSET 0x00
#define BMIS_OFFSET 0x02
#define BMID_OFFSET 0x04
//
// IDE transfer mode
//
#define EFI_ATA_MODE_DEFAULT_PIO 0x00
#define EFI_ATA_MODE_FLOW_PIO 0x01
#define EFI_ATA_MODE_MDMA 0x04
#define EFI_ATA_MODE_UDMA 0x08
typedef struct {
UINT32 RegionBaseAddr;
UINT16 ByteCount;
UINT16 EndOfTable;
} EFI_ATA_DMA_PRD;
typedef struct {
UINT8 ModeNumber : 3;
UINT8 ModeCategory : 5;
} EFI_ATA_TRANSFER_MODE;
typedef struct {
UINT8 Sector;
UINT8 Heads;
UINT8 MultipleSector;
} EFI_ATA_DRIVE_PARMS;
//
// IDE registers set
//
typedef struct {
UINT16 Data;
UINT16 ErrOrFeature;
UINT16 SectorCount;
UINT16 SectorNumber;
UINT16 CylinderLsb;
UINT16 CylinderMsb;
UINT16 Head;
UINT16 CmdOrStatus;
UINT16 AltOrDev;
UINT16 BusMasterBaseAddr;
} EFI_IDE_REGISTERS;
//
// Bit definitions in Programming Interface byte of the Class Code field
// in PCI IDE controller's Configuration Space
//
#define IDE_PRIMARY_OPERATING_MODE BIT0
#define IDE_PRIMARY_PROGRAMMABLE_INDICATOR BIT1
#define IDE_SECONDARY_OPERATING_MODE BIT2
#define IDE_SECONDARY_PROGRAMMABLE_INDICATOR BIT3
/**
Get IDE i/o port registers' base addresses by mode.
In 'Compatibility' mode, use fixed addresses.
In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's
Configuration Space.
The steps to get IDE i/o port registers' base addresses for each channel
as follows:
1. Examine the Programming Interface byte of the Class Code fields in PCI IDE
controller's Configuration Space to determine the operating mode.
2. a) In 'Compatibility' mode, use fixed addresses shown in the Table 1 below.
___________________________________________
| | Command Block | Control Block |
| Channel | Registers | Registers |
|___________|_______________|_______________|
| Primary | 1F0h - 1F7h | 3F6h - 3F7h |
|___________|_______________|_______________|
| Secondary | 170h - 177h | 376h - 377h |
|___________|_______________|_______________|
Table 1. Compatibility resource mappings
b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs
in IDE controller's PCI Configuration Space, shown in the Table 2 below.
___________________________________________________
| | Command Block | Control Block |
| Channel | Registers | Registers |
|___________|___________________|___________________|
| Primary | BAR at offset 0x10| BAR at offset 0x14|
|___________|___________________|___________________|
| Secondary | BAR at offset 0x18| BAR at offset 0x1C|
|___________|___________________|___________________|
Table 2. BARs for Register Mapping
@param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
@param[in, out] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
store the IDE i/o port registers' base addresses
@retval EFI_UNSUPPORTED Return this value when the BARs is not IO type
@retval EFI_SUCCESS Get the Base address successfully
@retval Other Read the pci configureation data error
**/
EFI_STATUS
EFIAPI
GetIdeRegisterIoAddr (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN OUT EFI_IDE_REGISTERS *IdeRegisters
);
/**
This function is used to send out ATAPI commands conforms to the Packet Command
with PIO Data In Protocol.
@param[in] PciIo Pointer to the EFI_PCI_IO_PROTOCOL instance
@param[in] IdeRegisters Pointer to EFI_IDE_REGISTERS which is used to
store the IDE i/o port registers' base addresses
@param[in] Channel The channel number of device.
@param[in] Device The device number of device.
@param[in] Packet A pointer to EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET data structure.
@retval EFI_SUCCESS send out the ATAPI packet command successfully
and device sends data successfully.
@retval EFI_DEVICE_ERROR the device failed to send data.
**/
EFI_STATUS
EFIAPI
AtaPacketCommandExecute (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters,
IN UINT8 Channel,
IN UINT8 Device,
IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
);
/**
Send ATA command into device with NON_DATA protocol
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
@param Timeout The time to complete the command.
@retval EFI_SUCCESS Reading succeed
@retval EFI_ABORTED Command failed
@retval EFI_DEVICE_ERROR Device status error.
**/
EFI_STATUS
EFIAPI
AtaNonDataCommandIn (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN UINT64 Timeout
);
/**
Perform an ATA Udma operation (Read, ReadExt, Write, WriteExt).
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
@param Read Flag used to determine the data transfer direction.
Read equals 1, means data transferred from device to host;
Read equals 0, means data transferred from host to device.
@param DataBuffer A pointer to the source buffer for the data.
@param DataLength The length of the data.
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
@param Timeout The time to complete the command.
@retval EFI_SUCCESS the operation is successful.
@retval EFI_OUT_OF_RESOURCES Build PRD table failed
@retval EFI_UNSUPPORTED Unknown channel or operations command
@retval EFI_DEVICE_ERROR Ata command execute failed
**/
EFI_STATUS
EFIAPI
AtaUdmaInOut (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters,
IN BOOLEAN Read,
IN VOID *DataBuffer,
IN UINT64 DataLength,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN UINT64 Timeout
);
/**
This function is used to send out ATA commands conforms to the PIO Data In Protocol.
@param PciIo A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.
@param IdeRegisters A pointer to EFI_IDE_REGISTERS data structure.
@param Buffer A pointer to the source buffer for the data.
@param ByteCount The length of the data.
@param Read Flag used to determine the data transfer direction.
Read equals 1, means data transferred from device to host;
Read equals 0, means data transferred from host to device.
@param AtaCommandBlock A pointer to EFI_ATA_COMMAND_BLOCK data structure.
@param AtaStatusBlock A pointer to EFI_ATA_STATUS_BLOCK data structure.
@param Timeout The time to complete the command.
@retval EFI_SUCCESS send out the ATA command and device send required data successfully.
@retval EFI_DEVICE_ERROR command sent failed.
**/
EFI_STATUS
EFIAPI
AtaPioDataInOut (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN EFI_IDE_REGISTERS *IdeRegisters,
IN OUT VOID *Buffer,
IN UINT64 ByteCount,
IN BOOLEAN Read,
IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,
IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,
IN UINT64 Timeout
);
#endif