2cc45b2a77348affaae369fdda855ce36d568c6a
[lunaix-os.git] / lunaix-os / includes / hal / pci.h
1 #ifndef __LUNAIX_PCI_H
2 #define __LUNAIX_PCI_H
3
4 #include <lunaix/ds/ldga.h>
5 #include <lunaix/ds/llist.h>
6 #include <lunaix/types.h>
7
8 #define PCI_TDEV 0x0
9 #define PCI_TPCIBRIDGE 0x1
10 #define PCI_TCARDBRIDGE 0x2
11
12 #define PCI_VENDOR_INVLD 0xffff
13
14 #define PCI_REG_VENDOR_DEV 0
15 #define PCI_REG_STATUS_CMD 0x4
16 #define PCI_REG_BAR(num) (0x10 + (num - 1) * 4)
17
18 #define PCI_DEV_VENDOR(x) ((x)&0xffff)
19 #define PCI_DEV_DEVID(x) ((x) >> 16)
20 #define PCI_INTR_IRQ(x) ((x)&0xff)
21 #define PCI_INTR_PIN(x) (((x)&0xff00) >> 8)
22 #define PCI_DEV_CLASS(x) ((x) >> 8)
23 #define PCI_DEV_REV(x) (((x)&0xff))
24 #define PCI_BUS_NUM(x) (((x) >> 16) & 0xff)
25 #define PCI_SLOT_NUM(x) (((x) >> 11) & 0x1f)
26 #define PCI_FUNCT_NUM(x) (((x) >> 8) & 0x7)
27
28 #define PCI_BAR_MMIO(x) (!((x)&0x1))
29 #define PCI_BAR_CACHEABLE(x) ((x)&0x8)
30 #define PCI_BAR_TYPE(x) ((x)&0x6)
31 #define PCI_BAR_ADDR_MM(x) ((x) & ~0xf)
32 #define PCI_BAR_ADDR_IO(x) ((x) & ~0x3)
33
34 #define PCI_MSI_ADDR(msi_base) ((msi_base) + 4)
35 #define PCI_MSI_DATA(msi_base, offset) ((msi_base) + 8 + offset)
36 #define PCI_MSI_MASK(msi_base, offset) ((msi_base) + 0xc + offset)
37
38 #define MSI_CAP_64BIT 0x80
39 #define MSI_CAP_MASK 0x100
40 #define MSI_CAP_ENABLE 0x1
41
42 #define PCI_RCMD_DISABLE_INTR (1 << 10)
43 #define PCI_RCMD_FAST_B2B (1 << 9)
44 #define PCI_RCMD_BUS_MASTER (1 << 2)
45 #define PCI_RCMD_MM_ACCESS (1 << 1)
46 #define PCI_RCMD_IO_ACCESS 1
47
48 #define PCI_ADDRESS(bus, dev, funct)                                           \
49     (((bus)&0xff) << 16) | (((dev)&0xff) << 11) | (((funct)&0xff) << 8) |      \
50       0x80000000
51
52 typedef unsigned int pci_reg_t;
53
54 // PCI device header format
55 // Ref: "PCI Local Bus Specification, Rev.3, Section 6.1"
56
57 #define BAR_TYPE_MMIO 0x1
58 #define BAR_TYPE_CACHABLE 0x2
59 #define PCI_DRV_NAME_LEN 32
60
61 #define EXPORT_PCI_DEVICE(name_, class, vendor_id, dev_id, init_fn)            \
62     static struct pci_driver pcidev_##name_ =                                  \
63       (struct pci_driver){ .name = #name_,                                     \
64                            .create_driver = (init_fn),                         \
65                            .dev_info = ((vendor_id) << 16) | (dev_id),         \
66                            .dev_class = (class) };                             \
67     export_ldga_el(pci_dev_drivers, name_, ptr_t, &pcidev_##name_)
68
69 struct pci_driver;
70
71 struct pci_base_addr
72 {
73     u32_t start;
74     u32_t size;
75     u32_t type;
76 };
77
78 struct pci_device
79 {
80     struct llist_header dev_chain;
81     u32_t device_info;
82     u32_t class_info;
83     u32_t cspace_base;
84     u32_t msi_loc;
85     u16_t intr_info;
86     struct
87     {
88         struct pci_driver* type;
89         void* instance;
90     } driver;
91     struct pci_base_addr bar[6];
92 };
93
94 typedef void* (*pci_drv_init)(struct pci_device*);
95
96 struct pci_driver
97 {
98     struct llist_header drivers;
99     u32_t dev_info;
100     u32_t dev_class;
101     pci_drv_init create_driver;
102     char name[PCI_DRV_NAME_LEN];
103 };
104
105 /**
106  * @brief 初始化PCI。这主要是通过扫描PCI总线进行拓扑重建。注意,该
107  * 初始化不包括针对每个设备的初始化,因为那是设备驱动的事情。
108  *
109  */
110 void
111 pci_load_devices();
112
113 /**
114  * @brief 根据类型代码(Class Code)去在拓扑中寻找一个设备
115  * 类型代码请参阅: PCI LB Spec. Appendix D.
116  *
117  * @return struct pci_device*
118  */
119 struct pci_device* pci_get_device_by_class(u32_t class);
120
121 /**
122  * @brief 根据设备商ID和设备ID,在拓扑中寻找一个设备
123  *
124  * @param vendorId
125  * @param deviceId
126  * @return struct pci_device*
127  */
128 struct pci_device*
129 pci_get_device_by_id(u16_t vendorId, u16_t deviceId);
130
131 /**
132  * @brief 初始化PCI设备的基地址寄存器。返回由该基地址代表的,
133  * 设备所使用的MMIO或I/O地址空间的,大小。
134  * 参阅:PCI LB Spec. (Rev 3) Section 6.2.5.1, Implementation Note.
135  *
136  * @param dev The PCI device
137  * @param bar_out Value in BAR
138  * @param bar_num The index of BAR (starting from 1)
139  * @return size_t
140  */
141 size_t
142 pci_bar_sizing(struct pci_device* dev, u32_t* bar_out, u32_t bar_num);
143
144 void
145 pci_add_driver(const char* name,
146                u32_t class,
147                u32_t vendor,
148                u32_t devid,
149                pci_drv_init init);
150
151 int
152 pci_bind_driver(struct pci_device* pci_dev);
153
154 void
155 pci_probe_bar_info(struct pci_device* device);
156
157 void
158 pci_probe_msi_info(struct pci_device* device);
159
160 #endif /* __LUNAIX_PCI_H */