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: _ }],
77 [ pci_card{ vendor: 16'8086, device: 16'10fb, function: _, subvendor: _, subdevice: _ }],
82 interrupt_model: [msix],
89 [ pci_card{ vendor: 16'10ec, device: 16'8029, function: _, subvendor: _, subdevice: _ } ],
94 platforms: ['x86_64', 'x86_32']
100 [ pci_card{ vendor: 16'8086, device: 16'225e, function: _, subvendor: _, subdevice: _ } ],
105 platforms: ['x86_64']
112 [ pci_card{ vendor: 16'8086, device: 16'0e20, function: _, subvendor: _, subdevice: _ },
113 pci_card{ vendor: 16'8086, device: 16'2f20, function: _, subvendor: _, subdevice: _ } ],
118 platforms: ['x86_64']
124 [ pci_card{ vendor: 16'8086, device: 16'2922, function: _, subvendor: _, subdevice: _ },
125 pci_card{ vendor: 16'8086, device: 16'3a22, function: _, subvendor: _, subdevice: _ },
126 pci_card{ vendor: 16'1002, device: 16'4390, function: _, subvendor: _, subdevice: _ } ],
131 platforms: ['x86_64', 'x86_32']
136 platforms: ['x86_64', 'x86_32']
142 platforms: ['x86_64', 'x86_32']
148 % Driver selection logic
151 % Picks from a list of IntModels one that is feasible on this system
152 % Currently, return first entry
153 int_model_enum(none, 0).
154 int_model_enum(legacy, 1).
155 int_model_enum(msi, 2).
156 int_model_enum(msix, 3).
158 get_interrupt_model(IntModels, Model) :-
159 ((var(IntModels) -> ModelAtom = none);
160 IntModels = [ModelAtom | _]),
161 int_model_enum(ModelAtom, Model).
163 find_pci_driver(PciInfo, DriverInfo) :-
164 PciInfo = pci_card{vendor:VId, device: DId, function: Fun, subvendor: SVId,
166 pci_driver{binary: Binary, supported_cards: _, core_hint: Core,
167 core_offset: Offset, multi_instance: Multi,
168 interrupt_load: IRQLoad, platforms: Platforms, interrupt_model: IntModels},
170 % We find the highest priority matching driver.
171 % TODO: The binary name is used as an identifier. Thus, multiple entries with the same
172 % binary are not supported
173 findall((Prio,X), (pci_driver{ supported_cards: Cards, binary: X, priority: Prio },
174 member(PciInfo, Cards)), LiU),
175 sort(0,>,LiU, [(_,Binary)|_]),
176 get_interrupt_model(IntModels, IntModel),
177 DriverInfo = driver(Core, Multi, Offset, Binary, IntModel).
179 find_cpu_driver(ApicId, DriverInfo) :-
180 cpu_driver{binary: Binary, platforms: Platforms},
181 % TODO: In future use ApicId to select cpu driver that has listed the correct
183 DriverInfo = driver(Binary).
185 find_ioapic_driver(IOApicId, DriverInfo) :-
186 bus_driver{binary: Binary, core_hint: Core, platforms: Platforms},
187 % TODO: Select appropriate Core based on core_hint, platform, ioapic id
188 DriverInfo = driver(Core, Binary).