--- /dev/null
+/** @file\r
+ Header file for AHCI mode of ATA host controller.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#ifndef __OPAL_PASSWORD_AHCI_MODE_H__\r
+#define __OPAL_PASSWORD_AHCI_MODE_H__\r
+\r
+//\r
+// OPAL LIBRARY CALLBACKS\r
+//\r
+#define ATA_COMMAND_TRUSTED_RECEIVE 0x5C\r
+#define ATA_COMMAND_TRUSTED_SEND 0x5E\r
+\r
+//\r
+// ATA TRUSTED commands express transfer Length in 512 byte multiple\r
+//\r
+#define ATA_TRUSTED_TRANSFER_LENGTH_MULTIPLE 512\r
+#define ATA_DEVICE_LBA 0x40 ///< Set for commands with LBA (rather than CHS) addresses\r
+\r
+\r
+#define EFI_AHCI_BAR_INDEX 0x05\r
+\r
+#define EFI_AHCI_CAPABILITY_OFFSET 0x0000\r
+#define EFI_AHCI_CAP_SAM BIT18\r
+#define EFI_AHCI_GHC_OFFSET 0x0004\r
+#define EFI_AHCI_GHC_RESET BIT0\r
+#define EFI_AHCI_GHC_IE BIT1\r
+#define EFI_AHCI_GHC_ENABLE BIT31\r
+#define EFI_AHCI_IS_OFFSET 0x0008\r
+#define EFI_AHCI_PI_OFFSET 0x000C\r
+\r
+typedef struct {\r
+ UINT32 Lower32;\r
+ UINT32 Upper32;\r
+} DATA_32;\r
+\r
+typedef union {\r
+ DATA_32 Uint32;\r
+ UINT64 Uint64;\r
+} DATA_64;\r
+\r
+//\r
+// Each PRDT entry can point to a memory block up to 4M byte\r
+//\r
+#define EFI_AHCI_MAX_DATA_PER_PRDT 0x400000\r
+\r
+#define EFI_AHCI_FIS_REGISTER_H2D 0x27 //Register FIS - Host to Device\r
+#define EFI_AHCI_FIS_REGISTER_H2D_LENGTH 20\r
+#define EFI_AHCI_FIS_REGISTER_D2H 0x34 //Register FIS - Device to Host\r
+#define EFI_AHCI_FIS_REGISTER_D2H_LENGTH 20\r
+#define EFI_AHCI_FIS_DMA_ACTIVATE 0x39 //DMA Activate FIS - Device to Host\r
+#define EFI_AHCI_FIS_DMA_ACTIVATE_LENGTH 4\r
+#define EFI_AHCI_FIS_DMA_SETUP 0x41 //DMA Setup FIS - Bi-directional\r
+#define EFI_AHCI_FIS_DMA_SETUP_LENGTH 28\r
+#define EFI_AHCI_FIS_DATA 0x46 //Data FIS - Bi-directional\r
+#define EFI_AHCI_FIS_BIST 0x58 //BIST Activate FIS - Bi-directional\r
+#define EFI_AHCI_FIS_BIST_LENGTH 12\r
+#define EFI_AHCI_FIS_PIO_SETUP 0x5F //PIO Setup FIS - Device to Host\r
+#define EFI_AHCI_FIS_PIO_SETUP_LENGTH 20\r
+#define EFI_AHCI_FIS_SET_DEVICE 0xA1 //Set Device Bits FIS - Device to Host\r
+#define EFI_AHCI_FIS_SET_DEVICE_LENGTH 8\r
+\r
+#define EFI_AHCI_D2H_FIS_OFFSET 0x40\r
+#define EFI_AHCI_DMA_FIS_OFFSET 0x00\r
+#define EFI_AHCI_PIO_FIS_OFFSET 0x20\r
+#define EFI_AHCI_SDB_FIS_OFFSET 0x58\r
+#define EFI_AHCI_FIS_TYPE_MASK 0xFF\r
+#define EFI_AHCI_U_FIS_OFFSET 0x60\r
+\r
+//\r
+// Port register\r
+//\r
+#define EFI_AHCI_PORT_START 0x0100\r
+#define EFI_AHCI_PORT_REG_WIDTH 0x0080\r
+#define EFI_AHCI_PORT_CLB 0x0000\r
+#define EFI_AHCI_PORT_CLBU 0x0004\r
+#define EFI_AHCI_PORT_FB 0x0008\r
+#define EFI_AHCI_PORT_FBU 0x000C\r
+#define EFI_AHCI_PORT_IS 0x0010\r
+#define EFI_AHCI_PORT_IS_DHRS BIT0\r
+#define EFI_AHCI_PORT_IS_PSS BIT1\r
+#define EFI_AHCI_PORT_IS_SSS BIT2\r
+#define EFI_AHCI_PORT_IS_SDBS BIT3\r
+#define EFI_AHCI_PORT_IS_UFS BIT4\r
+#define EFI_AHCI_PORT_IS_DPS BIT5\r
+#define EFI_AHCI_PORT_IS_PCS BIT6\r
+#define EFI_AHCI_PORT_IS_DIS BIT7\r
+#define EFI_AHCI_PORT_IS_PRCS BIT22\r
+#define EFI_AHCI_PORT_IS_IPMS BIT23\r
+#define EFI_AHCI_PORT_IS_OFS BIT24\r
+#define EFI_AHCI_PORT_IS_INFS BIT26\r
+#define EFI_AHCI_PORT_IS_IFS BIT27\r
+#define EFI_AHCI_PORT_IS_HBDS BIT28\r
+#define EFI_AHCI_PORT_IS_HBFS BIT29\r
+#define EFI_AHCI_PORT_IS_TFES BIT30\r
+#define EFI_AHCI_PORT_IS_CPDS BIT31\r
+#define EFI_AHCI_PORT_IS_CLEAR 0xFFFFFFFF\r
+#define EFI_AHCI_PORT_IS_FIS_CLEAR 0x0000000F\r
+\r
+#define EFI_AHCI_PORT_IE 0x0014\r
+#define EFI_AHCI_PORT_CMD 0x0018\r
+#define EFI_AHCI_PORT_CMD_ST_MASK 0xFFFFFFFE\r
+#define EFI_AHCI_PORT_CMD_ST BIT0\r
+#define EFI_AHCI_PORT_CMD_SUD BIT1\r
+#define EFI_AHCI_PORT_CMD_POD BIT2\r
+#define EFI_AHCI_PORT_CMD_COL BIT3\r
+#define EFI_AHCI_PORT_CMD_CR BIT15\r
+#define EFI_AHCI_PORT_CMD_FRE BIT4\r
+#define EFI_AHCI_PORT_CMD_FR BIT14\r
+#define EFI_AHCI_PORT_CMD_MASK ~(EFI_AHCI_PORT_CMD_ST | EFI_AHCI_PORT_CMD_FRE | EFI_AHCI_PORT_CMD_COL)\r
+#define EFI_AHCI_PORT_CMD_PMA BIT17\r
+#define EFI_AHCI_PORT_CMD_HPCP BIT18\r
+#define EFI_AHCI_PORT_CMD_MPSP BIT19\r
+#define EFI_AHCI_PORT_CMD_CPD BIT20\r
+#define EFI_AHCI_PORT_CMD_ESP BIT21\r
+#define EFI_AHCI_PORT_CMD_ATAPI BIT24\r
+#define EFI_AHCI_PORT_CMD_DLAE BIT25\r
+#define EFI_AHCI_PORT_CMD_ALPE BIT26\r
+#define EFI_AHCI_PORT_CMD_ASP BIT27\r
+#define EFI_AHCI_PORT_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | BIT31)\r
+#define EFI_AHCI_PORT_CMD_ACTIVE (1 << 28 )\r
+#define EFI_AHCI_PORT_TFD 0x0020\r
+#define EFI_AHCI_PORT_TFD_MASK (BIT7 | BIT3 | BIT0)\r
+#define EFI_AHCI_PORT_TFD_BSY BIT7\r
+#define EFI_AHCI_PORT_TFD_DRQ BIT3\r
+#define EFI_AHCI_PORT_TFD_ERR BIT0\r
+#define EFI_AHCI_PORT_TFD_ERR_MASK 0x00FF00\r
+#define EFI_AHCI_PORT_SIG 0x0024\r
+#define EFI_AHCI_PORT_SSTS 0x0028\r
+#define EFI_AHCI_PORT_SSTS_DET_MASK 0x000F\r
+#define EFI_AHCI_PORT_SSTS_DET 0x0001\r
+#define EFI_AHCI_PORT_SSTS_DET_PCE 0x0003\r
+#define EFI_AHCI_PORT_SSTS_SPD_MASK 0x00F0\r
+#define EFI_AHCI_PORT_SCTL 0x002C\r
+#define EFI_AHCI_PORT_SCTL_DET_MASK 0x000F\r
+#define EFI_AHCI_PORT_SCTL_MASK (~EFI_AHCI_PORT_SCTL_DET_MASK)\r
+#define EFI_AHCI_PORT_SCTL_DET_INIT 0x0001\r
+#define EFI_AHCI_PORT_SCTL_DET_PHYCOMM 0x0003\r
+#define EFI_AHCI_PORT_SCTL_SPD_MASK 0x00F0\r
+#define EFI_AHCI_PORT_SCTL_IPM_MASK 0x0F00\r
+#define EFI_AHCI_PORT_SCTL_IPM_INIT 0x0300\r
+#define EFI_AHCI_PORT_SCTL_IPM_PSD 0x0100\r
+#define EFI_AHCI_PORT_SCTL_IPM_SSD 0x0200\r
+#define EFI_AHCI_PORT_SERR 0x0030\r
+#define EFI_AHCI_PORT_SERR_RDIE BIT0\r
+#define EFI_AHCI_PORT_SERR_RCE BIT1\r
+#define EFI_AHCI_PORT_SERR_TDIE BIT8\r
+#define EFI_AHCI_PORT_SERR_PCDIE BIT9\r
+#define EFI_AHCI_PORT_SERR_PE BIT10\r
+#define EFI_AHCI_PORT_SERR_IE BIT11\r
+#define EFI_AHCI_PORT_SERR_PRC BIT16\r
+#define EFI_AHCI_PORT_SERR_PIE BIT17\r
+#define EFI_AHCI_PORT_SERR_CW BIT18\r
+#define EFI_AHCI_PORT_SERR_BDE BIT19\r
+#define EFI_AHCI_PORT_SERR_DE BIT20\r
+#define EFI_AHCI_PORT_SERR_CRCE BIT21\r
+#define EFI_AHCI_PORT_SERR_HE BIT22\r
+#define EFI_AHCI_PORT_SERR_LSE BIT23\r
+#define EFI_AHCI_PORT_SERR_TSTE BIT24\r
+#define EFI_AHCI_PORT_SERR_UFT BIT25\r
+#define EFI_AHCI_PORT_SERR_EX BIT26\r
+#define EFI_AHCI_PORT_ERR_CLEAR 0xFFFFFFFF\r
+#define EFI_AHCI_PORT_SACT 0x0034\r
+#define EFI_AHCI_PORT_CI 0x0038\r
+#define EFI_AHCI_PORT_SNTF 0x003C\r
+\r
+\r
+#pragma pack(1)\r
+//\r
+// Command List structure includes total 32 entries.\r
+// The entry Data structure is listed at the following.\r
+//\r
+typedef struct {\r
+ UINT32 AhciCmdCfl:5; //Command FIS Length\r
+ UINT32 AhciCmdA:1; //ATAPI\r
+ UINT32 AhciCmdW:1; //Write\r
+ UINT32 AhciCmdP:1; //Prefetchable\r
+ UINT32 AhciCmdR:1; //Reset\r
+ UINT32 AhciCmdB:1; //BIST\r
+ UINT32 AhciCmdC:1; //Clear Busy upon R_OK\r
+ UINT32 AhciCmdRsvd:1;\r
+ UINT32 AhciCmdPmp:4; //Port Multiplier Port\r
+ UINT32 AhciCmdPrdtl:16; //Physical Region Descriptor Table Length\r
+ UINT32 AhciCmdPrdbc; //Physical Region Descriptor Byte Count\r
+ UINT32 AhciCmdCtba; //Command Table Descriptor Base Address\r
+ UINT32 AhciCmdCtbau; //Command Table Descriptor Base Address Upper 32-BITs\r
+ UINT32 AhciCmdRsvd1[4];\r
+} EFI_AHCI_COMMAND_LIST;\r
+\r
+//\r
+// This is a software constructed FIS.\r
+// For Data transfer operations, this is the H2D Register FIS format as\r
+// specified in the Serial ATA Revision 2.6 specification.\r
+//\r
+typedef struct {\r
+ UINT8 AhciCFisType;\r
+ UINT8 AhciCFisPmNum:4;\r
+ UINT8 AhciCFisRsvd:1;\r
+ UINT8 AhciCFisRsvd1:1;\r
+ UINT8 AhciCFisRsvd2:1;\r
+ UINT8 AhciCFisCmdInd:1;\r
+ UINT8 AhciCFisCmd;\r
+ UINT8 AhciCFisFeature;\r
+ UINT8 AhciCFisSecNum;\r
+ UINT8 AhciCFisClyLow;\r
+ UINT8 AhciCFisClyHigh;\r
+ UINT8 AhciCFisDevHead;\r
+ UINT8 AhciCFisSecNumExp;\r
+ UINT8 AhciCFisClyLowExp;\r
+ UINT8 AhciCFisClyHighExp;\r
+ UINT8 AhciCFisFeatureExp;\r
+ UINT8 AhciCFisSecCount;\r
+ UINT8 AhciCFisSecCountExp;\r
+ UINT8 AhciCFisRsvd3;\r
+ UINT8 AhciCFisControl;\r
+ UINT8 AhciCFisRsvd4[4];\r
+ UINT8 AhciCFisRsvd5[44];\r
+} EFI_AHCI_COMMAND_FIS;\r
+\r
+//\r
+// ACMD: ATAPI command (12 or 16 bytes)\r
+//\r
+typedef struct {\r
+ UINT8 AtapiCmd[0x10];\r
+} EFI_AHCI_ATAPI_COMMAND;\r
+\r
+//\r
+// Physical Region Descriptor Table includes up to 65535 entries\r
+// The entry Data structure is listed at the following.\r
+// the actual entry number comes from the PRDTL field in the command\r
+// list entry for this command slot.\r
+//\r
+typedef struct {\r
+ UINT32 AhciPrdtDba; //Data Base Address\r
+ UINT32 AhciPrdtDbau; //Data Base Address Upper 32-BITs\r
+ UINT32 AhciPrdtRsvd;\r
+ UINT32 AhciPrdtDbc:22; //Data Byte Count\r
+ UINT32 AhciPrdtRsvd1:9;\r
+ UINT32 AhciPrdtIoc:1; //Interrupt on Completion\r
+} EFI_AHCI_COMMAND_PRDT;\r
+\r
+//\r
+// Command table Data strucute which is pointed to by the entry in the command list\r
+//\r
+typedef struct {\r
+ EFI_AHCI_COMMAND_FIS CommandFis; // A software constructed FIS.\r
+ EFI_AHCI_ATAPI_COMMAND AtapiCmd; // 12 or 16 bytes ATAPI cmd.\r
+ UINT8 Reserved[0x30];\r
+ EFI_AHCI_COMMAND_PRDT PrdtTable; // The scatter/gather list for Data transfer\r
+} EFI_AHCI_COMMAND_TABLE;\r
+\r
+//\r
+// Received FIS structure\r
+//\r
+typedef struct {\r
+ UINT8 AhciDmaSetupFis[0x1C]; // Dma Setup Fis: offset 0x00\r
+ UINT8 AhciDmaSetupFisRsvd[0x04];\r
+ UINT8 AhciPioSetupFis[0x14]; // Pio Setup Fis: offset 0x20\r
+ UINT8 AhciPioSetupFisRsvd[0x0C];\r
+ UINT8 AhciD2HRegisterFis[0x14]; // D2H Register Fis: offset 0x40\r
+ UINT8 AhciD2HRegisterFisRsvd[0x04];\r
+ UINT64 AhciSetDeviceBitsFis; // Set Device Bits Fix: offset 0x58\r
+ UINT8 AhciUnknownFis[0x40]; // Unkonwn Fis: offset 0x60\r
+ UINT8 AhciUnknownFisRsvd[0x60];\r
+} EFI_AHCI_RECEIVED_FIS;\r
+\r
+#pragma pack()\r
+\r
+typedef struct {\r
+ EFI_AHCI_RECEIVED_FIS *AhciRFis;\r
+ EFI_AHCI_COMMAND_LIST *AhciCmdList;\r
+ EFI_AHCI_COMMAND_TABLE *AhciCommandTable;\r
+} EFI_AHCI_REGISTERS;\r
+\r
+extern EFI_AHCI_REGISTERS mAhciRegisters;\r
+extern UINT32 mAhciBar;\r
+\r
+/**\r
+ Send Buffer cmd to specific device.\r
+\r
+ @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
+ @param Port The number of port.\r
+ @param PortMultiplier The timeout Value of stop.\r
+ @param Buffer The Data Buffer to store IDENTIFY PACKET Data.\r
+\r
+ @retval EFI_DEVICE_ERROR The cmd abort with error occurs.\r
+ @retval EFI_TIMEOUT The operation is time out.\r
+ @retval EFI_UNSUPPORTED The device is not ready for executing.\r
+ @retval EFI_SUCCESS The cmd executes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciIdentify (\r
+ IN EFI_AHCI_REGISTERS *AhciRegisters,\r
+ IN UINT8 Port,\r
+ IN UINT8 PortMultiplier,\r
+ IN OUT ATA_IDENTIFY_DATA *Buffer\r
+ );\r
+\r
+/**\r
+ Get AHCI mode base address registers' Value.\r
+\r
+ @param[in] Bus The bus number of ata host controller.\r
+ @param[in] Device The device number of ata host controller.\r
+ @param[in] Function The function number of ata host controller.\r
+\r
+ @retval EFI_UNSUPPORTED Return this Value when the BARs is not IO type\r
+ @retval EFI_SUCCESS Get the Base address successfully\r
+ @retval Other Read the pci configureation Data error\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetAhciBaseAddress (\r
+ IN UINTN Bus,\r
+ IN UINTN Device,\r
+ IN UINTN Function\r
+ );\r
+\r
+/**\r
+ Allocate transfer-related Data struct which is used at AHCI mode.\r
+\r
+ @retval EFI_OUT_OF_RESOURCE The allocation is failure.\r
+ @retval EFI_SUCCESS Successful to allocate memory.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciAllocateResource (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Free allocated transfer-related Data struct which is used at AHCI mode.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AhciFreeResource (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Initialize ATA host controller at AHCI mode.\r
+\r
+ The function is designed to initialize ATA host controller.\r
+\r
+ @param[in] Port The port number to do initialization.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciModeInitialize (\r
+ UINT8 Port\r
+ );\r
+\r
+/**\r
+ Start a PIO Data transfer on specific port.\r
+\r
+ @param AhciRegisters The pointer to the EFI_AHCI_REGISTERS.\r
+ @param Port The number of port.\r
+ @param PortMultiplier The timeout Value of stop.\r
+ @param AtapiCommand The atapi command will be used for the transfer.\r
+ @param AtapiCommandLength The Length of the atapi command.\r
+ @param Read The transfer direction.\r
+ @param AtaCommandBlock The EFI_ATA_COMMAND_BLOCK Data.\r
+ @param AtaStatusBlock The EFI_ATA_STATUS_BLOCK Data.\r
+ @param MemoryAddr The pointer to the Data Buffer.\r
+ @param DataCount The Data count to be transferred.\r
+ @param Timeout The timeout Value of non Data transfer.\r
+\r
+ @retval EFI_DEVICE_ERROR The PIO Data transfer abort with error occurs.\r
+ @retval EFI_TIMEOUT The operation is time out.\r
+ @retval EFI_UNSUPPORTED The device is not ready for transfer.\r
+ @retval EFI_SUCCESS The PIO Data transfer executes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciPioTransfer (\r
+ IN EFI_AHCI_REGISTERS *AhciRegisters,\r
+ IN UINT8 Port,\r
+ IN UINT8 PortMultiplier,\r
+ IN EFI_AHCI_ATAPI_COMMAND *AtapiCommand OPTIONAL,\r
+ IN UINT8 AtapiCommandLength,\r
+ IN BOOLEAN Read,\r
+ IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock,\r
+ IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock,\r
+ IN OUT VOID *MemoryAddr,\r
+ IN UINT32 DataCount,\r
+ IN UINT64 Timeout\r
+ );\r
+\r
+\r
+#endif\r
+\r