blob: 4d2d01eb414682333f1c21d36618311dfd699efc [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{
swissChilib35a5cf2021-05-30 12:22:18 -070022 uint vendor_device = pci_config_readd(bus, slot, func, 0);
23 ushort vendor = vendor_device & 0xffff;
swissChilica268482021-05-28 18:31:46 -070024
swissChili5fe85a12021-05-31 08:10:27 -070025 struct pci_device device;
26 device.valid = false;
swissChili77eb1472021-05-28 21:40:00 -070027
swissChilib35a5cf2021-05-30 12:22:18 -070028 if (vendor != 0xffff)
swissChili0d248832021-04-08 18:16:02 -070029 {
swissChili5fe85a12021-05-31 08:10:27 -070030 device.valid = true;
swissChilib35a5cf2021-05-30 12:22:18 -070031
swissChili5fe85a12021-05-31 08:10:27 -070032 device.device_id = vendor_device >> 16;
33 device.vendor = pci_vendor_by_id(vendor);
34
35 // 3rd dword
36 uint class_subclass = pci_config_readd(bus, slot, func, 2);
37 device.class = class_subclass >> 24;
38 device.subclass = (class_subclass >> 16) & 0xff;
39 device.prog_if = (class_subclass >> 8) & 0xff;
swissChilica268482021-05-28 18:31:46 -070040 }
swissChili5fe85a12021-05-31 08:10:27 -070041
42 return device;
swissChilica268482021-05-28 18:31:46 -070043}
44
45struct pci_vendor *pci_vendor_by_id(ushort id)
46{
47 // Find vendor using binary search
48
swissChili5fe85a12021-05-31 08:10:27 -070049 uint start = 0, max = pci_num_vendors;
swissChilica268482021-05-28 18:31:46 -070050
51 while (true)
52 {
53 if (max == start)
54 // Can't find one
55 return NULL;
56
57 uint guess = (max - start) / 2 + start;
58
59 if (pci_vendors[guess].id == id)
60 return &pci_vendors[guess];
61 else if (pci_vendors[guess].id > id)
62 max = guess;
63 else
64 start = guess;
65 }
swissChili0d248832021-04-08 18:16:02 -070066}
swissChili402a3832021-05-29 21:41:31 -070067
68void pci_print_devices()
69{
swissChili9bd74de2021-06-15 20:30:48 -070070 kprintf(INFO "Enumerating PCI devices:\n");
swissChili402a3832021-05-29 21:41:31 -070071 for (int bus = 0; bus < 0xff; bus++)
72 {
73 for (int slot = 0; slot < 32; slot++)
74 {
75 for (int func = 0; func < 8; func++)
76 {
swissChili5fe85a12021-05-31 08:10:27 -070077 struct pci_device dev = pci_check_device(bus, slot, func);
swissChili402a3832021-05-29 21:41:31 -070078
swissChili5fe85a12021-05-31 08:10:27 -070079 if (dev.valid)
swissChili402a3832021-05-29 21:41:31 -070080 {
swissChili9bd74de2021-06-15 20:30:48 -070081 kprintf(INFO "%d %d %d --- d:0x%x --- %d:%d:%d --- %s\n", bus,
swissChili5fe85a12021-05-31 08:10:27 -070082 slot, func, dev.device_id, dev.class, dev.subclass,
83 dev.prog_if, dev.vendor->name);
swissChili402a3832021-05-29 21:41:31 -070084 }
85 }
86 }
87 }
88}
swissChili5fe85a12021-05-31 08:10:27 -070089
90void pci_register_device_driver(struct pci_device_driver driver)
91{
92 if (num_drivers == size_drivers)
93 {
94 size_drivers += 8;
95 drivers = realloc(drivers, sizeof(struct pci_device_driver) * size_drivers);
96 }
97
98 driver.loaded = 0;
99 drivers[num_drivers++] = driver;
100}
101
102void pci_init()
103{
104 num_drivers = 0;
105 size_drivers = 4;
106 drivers = malloc(sizeof(struct pci_device_driver) * size_drivers);
107}
108
109void pci_load()
110{
111 for (int bus = 0; bus < 0xff; bus++)
112 {
113 for (int slot = 0; slot < 32; slot++)
114 {
115 for (int func = 0; func < 8; func++)
116 {
117 struct pci_device dev = pci_check_device(bus, slot, func);
118
119 // Do any drivers support this?
120
121 for (int i = 0; i < num_drivers; i++)
122 {
123 if (drivers[i].supports(&dev))
124 {
125 drivers[i].loaded++;
126 drivers[i].dev = dev;
127 drivers[i].init(dev, bus, slot, func);
128 }
129 }
130 }
131 }
132 }
133}
134
135void pci_print_drivers()
136{
swissChili9bd74de2021-06-15 20:30:48 -0700137 kprintf(INFO "Enumerating PCI device drivers:\n");
swissChili5fe85a12021-05-31 08:10:27 -0700138 for (int i = 0; i < num_drivers; i++)
139 {
140 for (int j = 0; j < drivers[i].loaded; j++)
141 {
142 struct pci_device_driver d = drivers[i];
swissChili9bd74de2021-06-15 20:30:48 -0700143 kprintf(INFO "Driver: %s, vendor: %s\n", d.generic_name, d.dev.vendor->name);
swissChili5fe85a12021-05-31 08:10:27 -0700144 }
145 }
146}