Trying to flesh out SATA port initialization
This commit is contained in:
parent
98b793f699
commit
d8467573fb
2 changed files with 56 additions and 5 deletions
|
|
@ -7,8 +7,15 @@
|
||||||
#define HBA_GHC_INTR_ENABLE (1 << 1)
|
#define HBA_GHC_INTR_ENABLE (1 << 1)
|
||||||
#define HBA_GHC_AHCI_ENABLE (1 << 31)
|
#define HBA_GHC_AHCI_ENABLE (1 << 31)
|
||||||
|
|
||||||
#define PORT_CMD_START (1 << 0)
|
#define PORT_CMD_START (1 << 0)
|
||||||
#define PORT_CMD_FIS_RECV_ENABLE (1 << 4)
|
#define PORT_CMD_SPIN_UP_DEVICE (1 << 1)
|
||||||
|
#define PORT_CMD_FIS_RECV_ENABLE (1 << 4)
|
||||||
|
#define PORT_CMD_FIS_RECV_RUNNING (1 << 14)
|
||||||
|
#define PORT_CMD_LIST_RUNNING (1 << 15)
|
||||||
|
|
||||||
|
#define PORT_TFD_STS_ERR (1 << 0)
|
||||||
|
#define PORT_TFD_STS_DRQ (1 << 3)
|
||||||
|
#define PORT_TFD_STS_BSY (1 << 7)
|
||||||
|
|
||||||
#define ATA_CMD_READ_SECTOR_EXT 0x24
|
#define ATA_CMD_READ_SECTOR_EXT 0x24
|
||||||
#define ATA_CMD_READ_DMA_EXT 0x25
|
#define ATA_CMD_READ_DMA_EXT 0x25
|
||||||
|
|
|
||||||
|
|
@ -181,8 +181,27 @@ void sata_init_port(int port_num)
|
||||||
memset((void *)port->recv_fis_ptr, 0, 256);
|
memset((void *)port->recv_fis_ptr, 0, 256);
|
||||||
memset((void *)port->buffer_ptr, 0, 1024);
|
memset((void *)port->buffer_ptr, 0, 1024);
|
||||||
|
|
||||||
// TODO make sure port is in idle state
|
// If the port is not already idling, we need to get it into the idle state
|
||||||
|
if (port->port_mem->cmd & (PORT_CMD_START | PORT_CMD_FIS_RECV_ENABLE | PORT_CMD_FIS_RECV_RUNNING | PORT_CMD_LIST_RUNNING)) {
|
||||||
|
port->port_mem->cmd &= ~PORT_CMD_START;
|
||||||
|
while (port->port_mem->cmd & PORT_CMD_LIST_RUNNING) {
|
||||||
|
__asm__ ("pause");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port->port_mem->cmd & PORT_CMD_FIS_RECV_ENABLE) {
|
||||||
|
port->port_mem->cmd &= ~PORT_CMD_FIS_RECV_ENABLE;
|
||||||
|
while (port->port_mem->cmd & PORT_CMD_FIS_RECV_RUNNING) {
|
||||||
|
__asm__ ("pause");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hard reset the port; this shouldn't be neccessary
|
||||||
|
port->port_mem->sctl = (port->port_mem->sctl & 0xFFFFFFF0) | 1;
|
||||||
|
Time deassert_time = time_add(time_current(), TIME_FROM_MS(2));
|
||||||
|
while (time_compare(time_current(), deassert_time) < 0) {}
|
||||||
|
port->port_mem->sctl = (port->port_mem->sctl & 0xFFFFFFF0) | 0;
|
||||||
|
|
||||||
// TODO determine how many command slots the HBA supports (CAP.NCS)
|
// TODO determine how many command slots the HBA supports (CAP.NCS)
|
||||||
|
|
||||||
// Register structures with the HBA port
|
// Register structures with the HBA port
|
||||||
|
|
@ -190,8 +209,29 @@ void sata_init_port(int port_num)
|
||||||
port->port_mem->fb = pa_to_value(port->recv_fis_pa);
|
port->port_mem->fb = pa_to_value(port->recv_fis_pa);
|
||||||
port->port_mem->cmd |= PORT_CMD_FIS_RECV_ENABLE;
|
port->port_mem->cmd |= PORT_CMD_FIS_RECV_ENABLE;
|
||||||
|
|
||||||
|
port->port_mem->cmd |= PORT_CMD_SPIN_UP_DEVICE;
|
||||||
|
|
||||||
// TODO clear the PxSERR register
|
// TODO clear the PxSERR register
|
||||||
port->port_mem->serr |= (1 << 9) | (1 << 10) | (1 << 11);
|
//port->port_mem->serr |= (1 << 9) | (1 << 10) | (1 << 11);
|
||||||
|
port->port_mem->serr = 0xFFFFFFFF;
|
||||||
|
port->port_mem->is = 0;
|
||||||
|
|
||||||
|
printf("Port %d State right before we write the start bit:\n", port_num);
|
||||||
|
printf("P%d.CI=%x\n", port_num, port->port_mem->ci);
|
||||||
|
printf("P%d.IS=%x\n", port_num, port->port_mem->is);
|
||||||
|
printf("P%d.CMD=%x\n", port_num, port->port_mem->cmd);
|
||||||
|
printf("P%d.TFD=%x\n", port_num, port->port_mem->tfd);
|
||||||
|
printf("P%d.SSTS=%x\n", port_num, port->port_mem->ssts);
|
||||||
|
printf("P%d.SCTL=%x\n", port_num, port->port_mem->sctl);
|
||||||
|
printf("P%d.SERR=%x\n", port_num, port->port_mem->serr);
|
||||||
|
printf("P%d.SACT=%x\n", port_num, port->port_mem->sact);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// Wait for indication that the SATA drive is ready
|
||||||
|
while (port->port_mem->tfd & (PORT_TFD_STS_ERR | PORT_TFD_STS_DRQ | PORT_TFD_STS_BSY)) {
|
||||||
|
__asm__ ("pause");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Start processing commands
|
// Start processing commands
|
||||||
port->port_mem->cmd |= PORT_CMD_START;
|
port->port_mem->cmd |= PORT_CMD_START;
|
||||||
|
|
@ -318,6 +358,10 @@ void sata_init()
|
||||||
__asm__ volatile ("" ::: "memory");
|
__asm__ volatile ("" ::: "memory");
|
||||||
|
|
||||||
hba.hba_mem->ghc |= HBA_GHC_HOST_RESET;
|
hba.hba_mem->ghc |= HBA_GHC_HOST_RESET;
|
||||||
|
while (hba.hba_mem->ghc & HBA_GHC_HOST_RESET) {
|
||||||
|
__asm__ ("pause");
|
||||||
|
}
|
||||||
|
|
||||||
hba.hba_mem->ghc |= HBA_GHC_AHCI_ENABLE;
|
hba.hba_mem->ghc |= HBA_GHC_AHCI_ENABLE;
|
||||||
|
|
||||||
printf("HBA.VS=%x\n", hba.hba_mem->vs);
|
printf("HBA.VS=%x\n", hba.hba_mem->vs);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue