Unifying External Interrupt System (#51)
[lunaix-os.git] / lunaix-os / hal / ahci / ahci_pci.c
1 #include <lunaix/spike.h>
2 #include <lunaix/status.h>
3
4 #include <hal/ahci/ahci.h>
5 #include <hal/pci.h>
6
7 static int
8 ahci_pci_create(struct device_def* def, morph_t* morphed)
9 {
10     struct pci_probe* probe;
11     struct device* dev;
12     struct pci_base_addr* bar6;
13     struct ahci_driver* ahci_drv;
14     irq_t irq;
15
16     probe = changeling_try_reveal(morphed, pci_probe_morpher);
17     if (!probe) {
18         return EINVAL;
19     }
20
21     bar6 = pci_device_bar(probe, 5);
22     assert_msg(pci_bar_mmio_space(bar6), "AHCI: BAR#6 is not MMIO.");
23
24     pci_reg_t cmd = 0;
25     pci_cmd_set_bus_master(&cmd);
26     pci_cmd_set_mmio(&cmd);
27     pci_cmd_set_msi(&cmd);
28     pci_apply_command(probe, cmd);
29     
30     assert(pci_capability_msi(probe));
31
32     irq = pci_declare_msi_irq(ahci_hba_isr, probe);
33     pci_assign_msi(probe, irq, NULL);
34
35     struct ahci_driver_param param = {
36         .mmio_base = bar6->start,
37         .mmio_size = bar6->size,
38         .irq = irq,
39     };
40
41     ahci_drv = ahci_driver_init(&param);
42     dev = device_allocvol(NULL, ahci_drv);
43
44     device_setname(dev_meta(dev), 
45                    "pci-ahci%d", devclass_mkvar(&def->class));
46
47     pci_bind_instance(probe, dev);
48
49     return 0;
50 }
51
52 static bool
53 ahci_pci_compat(struct pci_probe* probe)
54 {
55     return pci_device_class(probe) == AHCI_HBA_CLASS;
56 }
57
58 static int
59 ahci_pci_register(struct device_def* def)
60 {
61     return !pci_register_driver(def, ahci_pci_compat);
62 }
63
64
65 static struct device_def ahcidef = 
66 {
67     def_device_class(GENERIC, STORAGE, SATA),
68     def_device_name("Generic AHCI (pci-bus)"),
69
70     def_on_register(ahci_pci_register),
71     def_on_create(ahci_pci_create),
72
73     def_non_trivial
74 };
75 EXPORT_DEVICE(ahci, &ahcidef, load_postboot);