move msi-related functionality to generic isrm
[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     msi_vector_t msiv;
13
14     ahci_dev = PCI_DEVICE(dev);
15     bar6 = pci_device_bar(ahci_dev, 5);
16     assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
17
18     pci_reg_t cmd = 0;
19     pci_cmd_set_bus_master(&cmd);
20     pci_cmd_set_mmio(&cmd);
21     pci_cmd_set_msi(&cmd);
22     pci_apply_command(ahci_dev, cmd);
23     
24     assert(pci_capability_msi(ahci_dev));
25
26     msiv = isrm_msialloc(ahci_hba_isr);
27     pci_setup_msi(ahci_dev, msiv);
28
29     struct ahci_driver_param param = {
30         .mmio_base = bar6->start,
31         .mmio_size = bar6->size,
32         .ahci_iv = msi_vect(msiv),
33     };
34
35     ahci_drv = ahci_driver_init(&param);
36     pci_bind_instance(ahci_dev, ahci_drv);
37
38     return 0;
39 }
40
41 static int
42 ahci_pci_init(struct device_def* def)
43 {
44     return pci_bind_definition_all(pcidev_def(def));
45 }
46
47 static bool
48 ahci_pci_compat(struct pci_device_def* def, 
49                 struct pci_device* pcidev)
50 {
51     return pci_device_class(pcidev) == AHCI_HBA_CLASS;
52 }
53
54
55 static struct pci_device_def ahcidef = {
56     .devdef = { .class = DEVCLASS(DEVIF_PCI, DEVFN_STORAGE, DEV_SATA),
57                 .name = "Generic AHCI",
58                 .init = ahci_pci_init,
59                 .bind = ahci_pci_bind },
60     .test_compatibility = ahci_pci_compat
61 };
62 EXPORT_PCI_DEVICE(ahci, &ahcidef, load_postboot);