mirror of https://github.com/acidanthera/audk.git
436 lines
16 KiB
C
436 lines
16 KiB
C
/** @file
|
|
Header file for AHCI mode of ATA host controller.
|
|
|
|
Copyright (c) 2016 - 2018, 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 __OPAL_PASSWORD_AHCI_MODE_H__
|
|
#define __OPAL_PASSWORD_AHCI_MODE_H__
|
|
|
|
//
|
|
// OPAL LIBRARY CALLBACKS
|
|
//
|
|
#define ATA_COMMAND_TRUSTED_RECEIVE 0x5C
|
|
#define ATA_COMMAND_TRUSTED_SEND 0x5E
|
|
|
|
//
|
|
// ATA TRUSTED commands express transfer Length in 512 byte multiple
|
|
//
|
|
#define ATA_TRUSTED_TRANSFER_LENGTH_MULTIPLE 512
|
|
#define ATA_DEVICE_LBA 0x40 ///< Set for commands with LBA (rather than CHS) addresses
|
|
|
|
|
|
#define EFI_AHCI_BAR_INDEX 0x05
|
|
|
|
#define EFI_AHCI_CAPABILITY_OFFSET 0x0000
|
|
#define EFI_AHCI_CAP_SAM BIT18
|
|
#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;
|
|
|
|
//
|
|
// 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; // 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;
|
|
VOID *AhciRFisMapping;
|
|
EFI_AHCI_COMMAND_LIST *AhciCmdList;
|
|
VOID *AhciCmdListMapping;
|
|
EFI_AHCI_COMMAND_TABLE *AhciCommandTable;
|
|
VOID *AhciCommandTableMapping;
|
|
} EFI_AHCI_REGISTERS;
|
|
|
|
typedef struct {
|
|
VOID *Buffer;
|
|
VOID *BufferMapping;
|
|
EFI_AHCI_REGISTERS AhciRegisters;
|
|
UINT32 AhciBar;
|
|
} AHCI_CONTEXT;
|
|
|
|
/**
|
|
Send Buffer cmd to specific device.
|
|
|
|
@param AhciContext The pointer to the AHCI_CONTEXT.
|
|
@param Port The number of port.
|
|
@param PortMultiplier The timeout Value of stop.
|
|
@param Buffer The Data Buffer to store IDENTIFY PACKET Data.
|
|
|
|
@retval EFI_DEVICE_ERROR The cmd abort with error occurs.
|
|
@retval EFI_TIMEOUT The operation is time out.
|
|
@retval EFI_UNSUPPORTED The device is not ready for executing.
|
|
@retval EFI_SUCCESS The cmd executes successfully.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AhciIdentify (
|
|
IN AHCI_CONTEXT *AhciContext,
|
|
IN UINT8 Port,
|
|
IN UINT8 PortMultiplier,
|
|
IN OUT ATA_IDENTIFY_DATA *Buffer
|
|
);
|
|
|
|
/**
|
|
Allocate transfer-related data struct which is used at AHCI mode.
|
|
|
|
@param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
|
|
|
|
@retval EFI_OUT_OF_RESOURCE No enough resource.
|
|
@retval EFI_SUCCESS Successful to allocate resource.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AhciAllocateResource (
|
|
IN OUT AHCI_CONTEXT *AhciContext
|
|
);
|
|
|
|
/**
|
|
Free allocated transfer-related data struct which is used at AHCI mode.
|
|
|
|
@param[in, out] AhciContext The pointer to the AHCI_CONTEXT.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
AhciFreeResource (
|
|
IN OUT AHCI_CONTEXT *AhciContext
|
|
);
|
|
|
|
/**
|
|
Initialize ATA host controller at AHCI mode.
|
|
|
|
The function is designed to initialize ATA host controller.
|
|
|
|
@param[in] AhciContext The pointer to the AHCI_CONTEXT.
|
|
@param[in] Port The port number to do initialization.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
AhciModeInitialize (
|
|
IN AHCI_CONTEXT *AhciContext,
|
|
IN UINT8 Port
|
|
);
|
|
|
|
typedef struct _EFI_ATA_COMMAND_BLOCK {
|
|
UINT8 Reserved1[2];
|
|
UINT8 AtaCommand;
|
|
UINT8 AtaFeatures;
|
|
UINT8 AtaSectorNumber;
|
|
UINT8 AtaCylinderLow;
|
|
UINT8 AtaCylinderHigh;
|
|
UINT8 AtaDeviceHead;
|
|
UINT8 AtaSectorNumberExp;
|
|
UINT8 AtaCylinderLowExp;
|
|
UINT8 AtaCylinderHighExp;
|
|
UINT8 AtaFeaturesExp;
|
|
UINT8 AtaSectorCount;
|
|
UINT8 AtaSectorCountExp;
|
|
UINT8 Reserved2[6];
|
|
} EFI_ATA_COMMAND_BLOCK;
|
|
|
|
typedef struct _EFI_ATA_STATUS_BLOCK {
|
|
UINT8 Reserved1[2];
|
|
UINT8 AtaStatus;
|
|
UINT8 AtaError;
|
|
UINT8 AtaSectorNumber;
|
|
UINT8 AtaCylinderLow;
|
|
UINT8 AtaCylinderHigh;
|
|
UINT8 AtaDeviceHead;
|
|
UINT8 AtaSectorNumberExp;
|
|
UINT8 AtaCylinderLowExp;
|
|
UINT8 AtaCylinderHighExp;
|
|
UINT8 Reserved2;
|
|
UINT8 AtaSectorCount;
|
|
UINT8 AtaSectorCountExp;
|
|
UINT8 Reserved3[6];
|
|
} EFI_ATA_STATUS_BLOCK;
|
|
|
|
/**
|
|
Start a PIO Data transfer on specific port.
|
|
|
|
@param AhciContext The pointer to the AHCI_CONTEXT.
|
|
@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 AHCI_CONTEXT *AhciContext,
|
|
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
|
|
|