3 * @author Lunaixsky (zelong56@gmail.com)
4 * @brief A software implementation of Serial ATA AHCI 1.3.1 Specification
8 * @copyright Copyright (c) 2022
13 #include <lunaix/mm/mmio.h>
14 #include <lunaix/spike.h>
15 #include <lunaix/syslog.h>
19 static struct ahci_hba hba;
24 struct pci_device* ahci_dev = pci_get_device_by_class(0x10601);
25 assert_msg(ahci_dev, "AHCI: Not found.");
28 size = pci_bar_sizing(ahci_dev, &bar6, 6);
29 assert_msg(bar6 && PCI_BAR_MMIO(bar6), "AHCI: BAR#6 is not MMIO.");
31 hba.base = (hba_reg_t*)ioremap(PCI_BAR_ADDR_MM(bar6), size);
33 // Enable AHCI, Enable interrupt generation.
34 hba.base[HBA_RGHC] |= 0x80000002;
36 // As per section 3.1.1, this is 0 based value.
37 hba.ports_num = (hba.base[HBA_RCAP] & 0x1f) + 1;
38 hba.version = hba.base[HBA_RVER];
40 kprintf(KINFO "Version: %x; Ports: %d\n", hba.version, hba.ports_num);
42 hba_reg_t pmap = hba.base[HBA_RPI];
43 for (size_t i = 0; i < 32; i++, pmap = pmap >> 1) {
47 hba.ports[i] = (hba_reg_t*)(&hba.base[HBA_RPBASE] + i);
48 kprintf("\t Port#%d, clb: %p, fis: %p\n",
50 hba.ports[i][HBA_RPxCLB],
51 hba.ports[i][HBA_RPxFB]);
53 // TODO: (?) Rebasing each port's command list and FIS