AHCI data structure definitions.

This commit is contained in:
Ali Mashtizadeh 2014-07-02 09:58:48 -07:00
parent 7d031c1377
commit 162c27767e

View File

@ -48,16 +48,105 @@ typedef struct AHCIPort
uint32_t _rsvd2; // *Reserved*
} AHCIPort;
#define AHCIPORT_CMD_ICCMASK 0xF0000000 /* Interface Communication Control */
#define AHCIPORT_CMD_ICCSLUMBER 0x60000000 /* ICC Slumber */
#define AHCIPORT_CMD_ICCPARTIAL 0x20000000 /* ICC Partial */
#define AHCIPORT_CMD_ICCACTIVE 0x10000000 /* ICC Active */
#define AHCIPORT_CMD_ICCIDLE 0x00000000 /* ICC Idle */
#define AHCIPORT_CMD_ASP 0x08000000 /* Aggressive Slumber/Partial */
#define AHCIPORT_CMD_ALPE 0x04000000 /* Aggressive Link PM Enable */
#define AHCIPORT_CMD_DLAE 0x02000000 /* Drive LED on ATAPI Enable */
#define AHCIPORT_CMD_ATAPI 0x01000000 /* Device is ATAPI */
#define AHCIPORT_CMD_CPD 0x00100000 /* Cold Presence Detection */
#define AHCIPORT_CMD_ISP 0x00080000 /* Interlock Switch Attached */
#define AHCIPORT_CMD_HPCP 0x00040000 /* Hot Plug Capable Port */
#define AHCIPORT_CMD_PMA 0x00020000 /* Port Multiplier Attached */
#define AHCIPORT_CMD_CPS 0x00010000 /* Cold Presence State */
#define AHCIPORT_CMD_CR 0x00008000 /* Command List Running */
#define AHCIPORT_CMD_FR 0x00004000 /* FIS Receive Running */
#define AHCIPORT_CMD_ISS 0x00002000 /* Interlock Switch State */
#define AHCIPORT_CMD_FRE 0x00000010 /* FIS Receive Enable */
#define AHCIPORT_CMD_CLO 0x00000008 /* Command List Override */
#define AHCIPORT_CMD_POD 0x00000004 /* Power On Device */
#define AHCIPORT_CMD_SUD 0x00000002 /* Spin-Up Device */
#define AHCIPORT_CMD_ST 0x00000001 /* Start */
#define AHCI_ABAR 5
#define AHCI_PORT_OFFSET 0x100
#define AHCI_PORT_LENGTH 0x80
#define AHCI_MAX_PORTS 32
#define AHCI_MAX_CMDS 32
/*
* Request Structures
*/
typedef struct AHCICommandHeader
{
uint32_t descInfo;
uint32_t cmdStatus;
uint64_t ctba;
uint64_t _rsvd[2];
} AHCICommandHeader;
typedef struct AHCICommandList
{
AHCICommandHeader cmds[AHCI_MAX_CMDS];
} AHCICommandList;
/*
* AHCIPRDT - Physical Region Descriptor Table
*/
typedef struct AHCIPRDT
{
uint64_t dba; // Data Base Address
uint32_t _rsvd;
uint32_t descInfo; // Description Information
} AHCIPRDT;
/*
* AHCICommandTable
* This structure is exactly one machine page in size, we fill up the page
* with PRDT entries. AHCI supports up to 64K PRDT entries but on x86 we
* limit this to 248.
*/
typedef struct AHCICommandTable
{
uint8_t cfis[64]; // Command FIS
uint8_t acmd[32]; // ATAPI Command
uint8_t _rsvd[32];
AHCIPRDT prdt[248]; // Physical Region Descriptor Table
} AHCICommandTable;
/*
* Response Structures
*/
typedef struct AHCIRecvFIS
{
uint8_t dsfis[0x1c];
uint8_t _rsvd0[0x4];
uint8_t psfis[0x14];
uint8_t _rsvd1[0xc];
uint8_t rfis[0x14];
uint8_t _rsvd2[0x4];
uint8_t sdbfis[0x8];
uint8_t ufis[0x40];
uint8_t _rsvd3[0x60];
} AHCIRecvFIS;
/*
* AHCI
* Exceeds a single page need to use heap
*/
typedef struct AHCI
{
PCIDevice dev;
AHCIHostControl *hc;
AHCIPort *port[AHCI_MAX_PORTS];
AHCICommandList *clst[AHCI_MAX_PORTS];
AHCICommandTable *ctbl[AHCI_MAX_PORTS][AHCI_MAX_CMDS];
AHCIRecvFIS *rfis[AHCI_MAX_PORTS];
} AHCI;
void AHCI_Configure(PCIDevice dev);
@ -97,6 +186,29 @@ AHCI_Init(uint32_t bus, uint32_t slot, uint32_t func)
void
AHCI_ResetPort(AHCI *ahci, int port)
{
volatile AHCIPort *p = ahci->port[port];
uint32_t cmd = p->cmd;
uint32_t cmd_mask = AHCIPORT_CMD_ST | AHCIPORT_CMD_CR |
AHCIPORT_CMD_FRE | AHCIPORT_CMD_FR;
// Wait for controller to be idle
if (cmd & cmd_mask != 0) {
int tries;
for (tries = 0; tries < 2; tries++) {
cmd = cmd & ~(AHCIPORT_CMD_ST | AHCIPORT_CMD_FRE);
p->cmd = cmd;
// sleep 500ms
cmd = p->cmd;
if (cmd & cmd_mask != 0) {
kprintf("AHCI: failed to reset port %d\n", port);
}
}
}
// Reset error
p->serr = 0xFFFFFFFF;
//
}
void