blob: bb0b36cffb17706274af7633a13d71953eeddf21 [file] [log] [blame]
swissChilie8491742021-04-08 20:38:06 -07001#include <dri/pci/pci.h>
swissChilica268482021-05-28 18:31:46 -07002#include <dri/pci/vendors.h>
3#include <io.h>
4#include <log.h>
swissChili5fe85a12021-05-31 08:10:27 -07005#include <alloc.h>
6
7static uint num_drivers, size_drivers;
8static struct pci_device_driver *drivers;
swissChili0d248832021-04-08 18:16:02 -07009
swissChili93214982021-05-28 21:32:26 -070010uint pci_config_readd(uchar bus, uchar slot, uchar func, uchar offset)
swissChili0d248832021-04-08 18:16:02 -070011{
swissChili5fe85a12021-05-31 08:10:27 -070012 uint address =
13 (bus << 16) | (slot << 11) | (func << 8) | (offset << 2) | 0x80000000;
swissChilica268482021-05-28 18:31:46 -070014
15 outl(PCI_CONFIG_ADDRESS, address);
16
17 return inl(PCI_CONFIG_DATA);
18}
19
swissChili5fe85a12021-05-31 08:10:27 -070020struct pci_device pci_check_device(uchar bus, uchar slot, uchar func)
swissChilica268482021-05-28 18:31:46 -070021{
swissChilid00ec612022-01-16 21:21:29 -080022
swissChilib35a5cf2021-05-30 12:22:18 -070023 uint vendor_device = pci_config_readd(bus, slot, func, 0);
24 ushort vendor = vendor_device & 0xffff;
swissChilica268482021-05-28 18:31:46 -070025
swissChili5fe85a12021-05-31 08:10:27 -070026 struct pci_device device;
27 device.valid = false;
swissChili77eb1472021-05-28 21:40:00 -070028
swissChilib35a5cf2021-05-30 12:22:18 -070029 if (vendor != 0xffff)
swissChili0d248832021-04-08 18:16:02 -070030 {
swissChili5fe85a12021-05-31 08:10:27 -070031 device.valid = true;
swissChilib35a5cf2021-05-30 12:22:18 -070032
swissChili5fe85a12021-05-31 08:10:27 -070033 device.device_id = vendor_device >> 16;
34 device.vendor = pci_vendor_by_id(vendor);
35
36 // 3rd dword
37 uint class_subclass = pci_config_readd(bus, slot, func, 2);
38 device.class = class_subclass >> 24;
39 device.subclass = (class_subclass >> 16) & 0xff;
40 device.prog_if = (class_subclass >> 8) & 0xff;
swissChilica268482021-05-28 18:31:46 -070041 }
swissChili5fe85a12021-05-31 08:10:27 -070042
43 return device;
swissChilica268482021-05-28 18:31:46 -070044}
45
46struct pci_vendor *pci_vendor_by_id(ushort id)
47{
48 // Find vendor using binary search
49
swissChili5fe85a12021-05-31 08:10:27 -070050 uint start = 0, max = pci_num_vendors;
swissChilica268482021-05-28 18:31:46 -070051
52 while (true)
53 {
54 if (max == start)
55 // Can't find one
56 return NULL;
57
58 uint guess = (max - start) / 2 + start;
59
60 if (pci_vendors[guess].id == id)
61 return &pci_vendors[guess];
62 else if (pci_vendors[guess].id > id)
63 max = guess;
64 else
65 start = guess;
66 }
swissChili0d248832021-04-08 18:16:02 -070067}
swissChili402a3832021-05-29 21:41:31 -070068
69void pci_print_devices()
70{
swissChili9bd74de2021-06-15 20:30:48 -070071 kprintf(INFO "Enumerating PCI devices:\n");
swissChili402a3832021-05-29 21:41:31 -070072 for (int bus = 0; bus < 0xff; bus++)
73 {
74 for (int slot = 0; slot < 32; slot++)
75 {
76 for (int func = 0; func < 8; func++)
77 {
swissChili5fe85a12021-05-31 08:10:27 -070078 struct pci_device dev = pci_check_device(bus, slot, func);
swissChili402a3832021-05-29 21:41:31 -070079
swissChili5fe85a12021-05-31 08:10:27 -070080 if (dev.valid)
swissChili402a3832021-05-29 21:41:31 -070081 {
swissChili9bd74de2021-06-15 20:30:48 -070082 kprintf(INFO "%d %d %d --- d:0x%x --- %d:%d:%d --- %s\n", bus,
swissChili5fe85a12021-05-31 08:10:27 -070083 slot, func, dev.device_id, dev.class, dev.subclass,
84 dev.prog_if, dev.vendor->name);
swissChili402a3832021-05-29 21:41:31 -070085 }
86 }
87 }
88 }
89}
swissChili5fe85a12021-05-31 08:10:27 -070090
91void pci_register_device_driver(struct pci_device_driver driver)
92{
93 if (num_drivers == size_drivers)
94 {
95 size_drivers += 8;
96 drivers = realloc(drivers, sizeof(struct pci_device_driver) * size_drivers);
97 }
98
99 driver.loaded = 0;
100 drivers[num_drivers++] = driver;
101}
102
103void pci_init()
104{
105 num_drivers = 0;
106 size_drivers = 4;
107 drivers = malloc(sizeof(struct pci_device_driver) * size_drivers);
108}
109
110void pci_load()
111{
112 for (int bus = 0; bus < 0xff; bus++)
113 {
114 for (int slot = 0; slot < 32; slot++)
115 {
116 for (int func = 0; func < 8; func++)
117 {
118 struct pci_device dev = pci_check_device(bus, slot, func);
119
120 // Do any drivers support this?
121
122 for (int i = 0; i < num_drivers; i++)
123 {
124 if (drivers[i].supports(&dev))
125 {
126 drivers[i].loaded++;
127 drivers[i].dev = dev;
128 drivers[i].init(dev, bus, slot, func);
129 }
130 }
131 }
132 }
133 }
134}
135
136void pci_print_drivers()
137{
swissChili9bd74de2021-06-15 20:30:48 -0700138 kprintf(INFO "Enumerating PCI device drivers:\n");
swissChili5fe85a12021-05-31 08:10:27 -0700139 for (int i = 0; i < num_drivers; i++)
140 {
141 for (int j = 0; j < drivers[i].loaded; j++)
142 {
143 struct pci_device_driver d = drivers[i];
swissChili9bd74de2021-06-15 20:30:48 -0700144 kprintf(INFO "Driver: %s, vendor: %s\n", d.generic_name, d.dev.vendor->name);
swissChili5fe85a12021-05-31 08:10:27 -0700145 }
146 }
147}