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*
|
uint32_t _rsvd2; // *Reserved*
|
||||||
} AHCIPort;
|
} 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_ABAR 5
|
||||||
#define AHCI_PORT_OFFSET 0x100
|
#define AHCI_PORT_OFFSET 0x100
|
||||||
#define AHCI_PORT_LENGTH 0x80
|
#define AHCI_PORT_LENGTH 0x80
|
||||||
#define AHCI_MAX_PORTS 32
|
#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
|
typedef struct AHCI
|
||||||
{
|
{
|
||||||
PCIDevice dev;
|
PCIDevice dev;
|
||||||
AHCIHostControl *hc;
|
AHCIHostControl *hc;
|
||||||
AHCIPort *port[AHCI_MAX_PORTS];
|
AHCIPort *port[AHCI_MAX_PORTS];
|
||||||
|
AHCICommandList *clst[AHCI_MAX_PORTS];
|
||||||
|
AHCICommandTable *ctbl[AHCI_MAX_PORTS][AHCI_MAX_CMDS];
|
||||||
|
AHCIRecvFIS *rfis[AHCI_MAX_PORTS];
|
||||||
} AHCI;
|
} AHCI;
|
||||||
|
|
||||||
void AHCI_Configure(PCIDevice dev);
|
void AHCI_Configure(PCIDevice dev);
|
||||||
@ -97,6 +186,29 @@ AHCI_Init(uint32_t bus, uint32_t slot, uint32_t func)
|
|||||||
void
|
void
|
||||||
AHCI_ResetPort(AHCI *ahci, int port)
|
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
|
void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user