AHCI data structure definitions.
This commit is contained in:
parent
7d031c1377
commit
162c27767e
112
sys/dev/ahci.c
112
sys/dev/ahci.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user