1 :- local struct(pci_driver(
2 binary, % Name of driver binary
3 supported_cards, % List of cards this binary supports
4 core_hint, % Preferred core to start the driver
5 core_offset, % Core offset where to start the drivers (multi instance)
6 multi_instance, % Allow multi instances of the driver
7 interrupt_load, % Expected Interrupt load
8 interrupt_model, % List of supported int models. legacy,msi,msix
9 platforms, % List of architectures the driver runs on
10 priority % When more than one driver matches, the higher prio gets started
13 :- dynamic(pci_driver/9).
15 :- local struct(cpu_driver(
16 binary, % Name of driver binary
17 platforms % List of architectures the driver runs on
20 :- local struct(bus_driver(
21 binary, % Name of driver binary
22 core_hint, % Preferred core to start the driver
23 platforms % List of architectures the driver runs on
26 :- local struct(pci_card(
27 vendor, % PCI Vendor ID
28 device, % PCI Device ID
42 [ pci_card{ vendor: 16'8086, device: 16'1521, function: _, subvendor: _, subdevice: _ },
43 pci_card{ vendor: 16'8086, device: 16'107d, function: _, subvendor: _, subdevice: _ },
44 pci_card{ vendor: 16'8086, device: 16'107e, function: _, subvendor: _, subdevice: _ },
45 pci_card{ vendor: 16'8086, device: 16'107f, function: _, subvendor: _, subdevice: _ },
46 pci_card{ vendor: 16'8086, device: 16'10b9, function: _, subvendor: _, subdevice: _ },
47 pci_card{ vendor: 16'8086, device: 16'1096, function: _, subvendor: _, subdevice: _ },
48 pci_card{ vendor: 16'8086, device: 16'100e, function: _, subvendor: _, subdevice: _ },
49 pci_card{ vendor: 16'8086, device: 16'10c9, function: _, subvendor: _, subdevice: _ },
50 pci_card{ vendor: 16'8086, device: 16'10a7, function: _, subvendor: _, subdevice: _ },
51 pci_card{ vendor: 16'8086, device: 16'10d3, function: _, subvendor: _, subdevice: _ },
52 pci_card{ vendor: 16'8086, device: 16'1079, function: _, subvendor: _, subdevice: _ },
53 pci_card{ vendor: 16'8086, device: 16'1533, function: _, subvendor: _, subdevice: _ } ],
58 platforms: ['x86_64', 'x86_32']
65 [ pci_card{ vendor: 16'1924, device: 16'0803, function: _, subvendor: _, subdevice: _ }],
76 [ pci_card{ vendor: 16'10ec, device: 16'8029, function: _, subvendor: _, subdevice: _ } ],
81 platforms: ['x86_64', 'x86_32']
87 [ pci_card{ vendor: 16'8086, device: 16'225e, function: _, subvendor: _, subdevice: _ } ],
99 [ pci_card{ vendor: 16'8086, device: 16'0e20, function: _, subvendor: _, subdevice: _ },
100 pci_card{ vendor: 16'8086, device: 16'2f20, function: _, subvendor: _, subdevice: _ } ],
105 platforms: ['x86_64']
111 [ pci_card{ vendor: 16'8086, device: 16'2922, function: _, subvendor: _, subdevice: _ },
112 pci_card{ vendor: 16'8086, device: 16'3a22, function: _, subvendor: _, subdevice: _ },
113 pci_card{ vendor: 16'1002, device: 16'4390, function: _, subvendor: _, subdevice: _ } ],
118 platforms: ['x86_64', 'x86_32']
123 platforms: ['x86_64', 'x86_32']
129 platforms: ['x86_64', 'x86_32']
135 % Driver selection logic
138 % Picks from a list of IntModels one that is feasible on this system
139 % Currently, return first entry
140 int_model_enum(none, 0).
141 int_model_enum(legacy, 1).
142 int_model_enum(msi, 2).
143 int_model_enum(msix, 3).
145 get_interrupt_model(IntModels, Model) :-
146 ((var(IntModels) -> ModelAtom = none);
147 IntModels = [ModelAtom | _]),
148 int_model_enum(ModelAtom, Model).
150 find_pci_driver(PciInfo, DriverInfo) :-
151 PciInfo = pci_card{vendor:VId, device: DId, function: Fun, subvendor: SVId,
153 pci_driver{binary: Binary, supported_cards: _, core_hint: Core,
154 core_offset: Offset, multi_instance: Multi,
155 interrupt_load: IRQLoad, platforms: Platforms, interrupt_model: IntModels},
157 % We find the highest priority matching driver.
158 % TODO: The binary name is used as an identifier. Thus, multiple entries with the same
159 % binary are not supported
160 findall((Prio,X), (pci_driver{ supported_cards: Cards, binary: X, priority: Prio },
161 member(PciInfo, Cards)), LiU),
162 sort(0,>,LiU, [(_,Binary)|_]),
163 get_interrupt_model(IntModels, IntModel),
164 DriverInfo = driver(Core, Multi, Offset, Binary, IntModel).
166 find_cpu_driver(ApicId, DriverInfo) :-
167 cpu_driver{binary: Binary, platforms: Platforms},
168 % TODO: In future use ApicId to select cpu driver that has listed the correct
170 DriverInfo = driver(Binary).
172 find_ioapic_driver(IOApicId, DriverInfo) :-
173 bus_driver{binary: Binary, core_hint: Core, platforms: Platforms},
174 % TODO: Select appropriate Core based on core_hint, platform, ioapic id
175 DriverInfo = driver(Core, Binary).