6c59cf8455e76935d7220cc9b95581171788c7fb
[lunaix-os.git] / lunaix-os / hal / ahci / ahci_pci.c
1 #include <lunaix/spike.h>
2
3 #include <hal/ahci/ahci.h>
4 #include <hal/pci.h>
5
6 static int
7 ahci_pci_bind(struct device_def* def, struct device* dev)
8 {
9     struct pci_device* ahci_dev;
10     struct pci_base_addr* bar6;
11     struct ahci_driver* ahci_drv;
12
13     ahci_dev = PCI_DEVICE(dev);
14     bar6 = pci_device_bar(ahci_dev, 5);
15     assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
16
17     pci_reg_t cmd = 0;
18     pci_cmd_set_bus_master(&cmd);
19     pci_cmd_set_mmio(&cmd);
20     pci_cmd_set_msi(&cmd);
21     pci_apply_command(ahci_dev, cmd);
22
23     int iv;
24     if (pci_capability_msi(ahci_dev)) {
25         iv = isrm_ivexalloc(ahci_hba_isr);
26         pci_setup_msi(ahci_dev, iv);
27     }
28     else {
29         iv = pci_intr_irq(ahci_dev);
30         iv = isrm_bindirq(iv, ahci_hba_isr);
31     }
32
33     struct ahci_driver_param param = {
34         .mmio_base = bar6->start,
35         .mmio_size = bar6->size,
36         .ahci_iv = iv,
37     };
38
39     ahci_drv = ahci_driver_init(&param);
40     pci_bind_instance(ahci_dev, ahci_drv);
41
42     return 0;
43 }
44
45 static int
46 ahci_pci_init(struct device_def* def)
47 {
48     return pci_bind_definition_all(pcidev_def(def));
49 }
50
51 static bool
52 ahci_pci_compat(struct pci_device_def* def, 
53                 struct pci_device* pcidev)
54 {
55     return pci_device_class(pcidev) == AHCI_HBA_CLASS;
56 }
57
58
59 static struct pci_device_def ahcidef = {
60     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
61                 .name = "Generic AHCI",
62                 .init = ahci_pci_init,
63                 .bind = ahci_pci_bind },
64     .test_compatibility = ahci_pci_compat
65 };
66 EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot);