]>
Commit | Line | Data |
---|---|---|
de9768f0 DC |
1 | package PVE::QemuServer::PCI; |
2 | ||
3 | use base 'Exporter'; | |
4 | ||
5 | our @EXPORT_OK = qw( | |
6 | print_pci_addr | |
7 | print_pcie_addr | |
c4e16381 | 8 | print_pcie_root_port |
de9768f0 DC |
9 | ); |
10 | ||
d7d698f6 TL |
11 | my $pci_addr_map; |
12 | sub get_pci_addr_map { | |
13 | $pci_addr_map = { | |
14 | piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci) }, | |
15 | ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of piix3 on arm | |
16 | vga => { bus => 0, addr => 2 }, | |
17 | balloon0 => { bus => 0, addr => 3 }, | |
18 | watchdog => { bus => 0, addr => 4 }, | |
19 | scsihw0 => { bus => 0, addr => 5, conflict_ok => qw(pci.3) }, | |
20 | 'pci.3' => { bus => 0, addr => 5, conflict_ok => qw(scsihw0) }, # also used for virtio-scsi-single bridge | |
21 | scsihw1 => { bus => 0, addr => 6 }, | |
22 | ahci0 => { bus => 0, addr => 7 }, | |
23 | qga0 => { bus => 0, addr => 8 }, | |
24 | spice => { bus => 0, addr => 9 }, | |
25 | virtio0 => { bus => 0, addr => 10 }, | |
26 | virtio1 => { bus => 0, addr => 11 }, | |
27 | virtio2 => { bus => 0, addr => 12 }, | |
28 | virtio3 => { bus => 0, addr => 13 }, | |
29 | virtio4 => { bus => 0, addr => 14 }, | |
30 | virtio5 => { bus => 0, addr => 15 }, | |
31 | hostpci0 => { bus => 0, addr => 16 }, | |
32 | hostpci1 => { bus => 0, addr => 17 }, | |
33 | net0 => { bus => 0, addr => 18 }, | |
34 | net1 => { bus => 0, addr => 19 }, | |
35 | net2 => { bus => 0, addr => 20 }, | |
36 | net3 => { bus => 0, addr => 21 }, | |
37 | net4 => { bus => 0, addr => 22 }, | |
38 | net5 => { bus => 0, addr => 23 }, | |
39 | vga1 => { bus => 0, addr => 24 }, | |
40 | vga2 => { bus => 0, addr => 25 }, | |
41 | vga3 => { bus => 0, addr => 26 }, | |
42 | hostpci2 => { bus => 0, addr => 27 }, | |
43 | hostpci3 => { bus => 0, addr => 28 }, | |
44 | #addr29 : usb-host (pve-usb.cfg) | |
45 | 'pci.1' => { bus => 0, addr => 30 }, | |
46 | 'pci.2' => { bus => 0, addr => 31 }, | |
47 | 'net6' => { bus => 1, addr => 1 }, | |
48 | 'net7' => { bus => 1, addr => 2 }, | |
49 | 'net8' => { bus => 1, addr => 3 }, | |
50 | 'net9' => { bus => 1, addr => 4 }, | |
51 | 'net10' => { bus => 1, addr => 5 }, | |
52 | 'net11' => { bus => 1, addr => 6 }, | |
53 | 'net12' => { bus => 1, addr => 7 }, | |
54 | 'net13' => { bus => 1, addr => 8 }, | |
55 | 'net14' => { bus => 1, addr => 9 }, | |
56 | 'net15' => { bus => 1, addr => 10 }, | |
57 | 'net16' => { bus => 1, addr => 11 }, | |
58 | 'net17' => { bus => 1, addr => 12 }, | |
59 | 'net18' => { bus => 1, addr => 13 }, | |
60 | 'net19' => { bus => 1, addr => 14 }, | |
61 | 'net20' => { bus => 1, addr => 15 }, | |
62 | 'net21' => { bus => 1, addr => 16 }, | |
63 | 'net22' => { bus => 1, addr => 17 }, | |
64 | 'net23' => { bus => 1, addr => 18 }, | |
65 | 'net24' => { bus => 1, addr => 19 }, | |
66 | 'net25' => { bus => 1, addr => 20 }, | |
67 | 'net26' => { bus => 1, addr => 21 }, | |
68 | 'net27' => { bus => 1, addr => 22 }, | |
69 | 'net28' => { bus => 1, addr => 23 }, | |
70 | 'net29' => { bus => 1, addr => 24 }, | |
71 | 'net30' => { bus => 1, addr => 25 }, | |
72 | 'net31' => { bus => 1, addr => 26 }, | |
73 | 'xhci' => { bus => 1, addr => 27 }, | |
2513b862 | 74 | 'pci.4' => { bus => 1, addr => 28 }, |
2cf61f33 | 75 | 'rng0' => { bus => 1, addr => 29 }, |
d7d698f6 TL |
76 | 'virtio6' => { bus => 2, addr => 1 }, |
77 | 'virtio7' => { bus => 2, addr => 2 }, | |
78 | 'virtio8' => { bus => 2, addr => 3 }, | |
79 | 'virtio9' => { bus => 2, addr => 4 }, | |
80 | 'virtio10' => { bus => 2, addr => 5 }, | |
81 | 'virtio11' => { bus => 2, addr => 6 }, | |
82 | 'virtio12' => { bus => 2, addr => 7 }, | |
83 | 'virtio13' => { bus => 2, addr => 8 }, | |
84 | 'virtio14' => { bus => 2, addr => 9 }, | |
85 | 'virtio15' => { bus => 2, addr => 10 }, | |
86 | 'ivshmem' => { bus => 2, addr => 11 }, | |
87 | 'audio0' => { bus => 2, addr => 12 }, | |
88 | hostpci4 => { bus => 2, addr => 13 }, | |
89 | hostpci5 => { bus => 2, addr => 14 }, | |
90 | hostpci6 => { bus => 2, addr => 15 }, | |
91 | hostpci7 => { bus => 2, addr => 16 }, | |
92 | hostpci8 => { bus => 2, addr => 17 }, | |
93 | hostpci9 => { bus => 2, addr => 18 }, | |
94 | hostpci10 => { bus => 2, addr => 19 }, | |
95 | hostpci11 => { bus => 2, addr => 20 }, | |
96 | hostpci12 => { bus => 2, addr => 21 }, | |
97 | hostpci13 => { bus => 2, addr => 22 }, | |
98 | hostpci14 => { bus => 2, addr => 23 }, | |
99 | hostpci15 => { bus => 2, addr => 24 }, | |
100 | 'virtioscsi0' => { bus => 3, addr => 1 }, | |
101 | 'virtioscsi1' => { bus => 3, addr => 2 }, | |
102 | 'virtioscsi2' => { bus => 3, addr => 3 }, | |
103 | 'virtioscsi3' => { bus => 3, addr => 4 }, | |
104 | 'virtioscsi4' => { bus => 3, addr => 5 }, | |
105 | 'virtioscsi5' => { bus => 3, addr => 6 }, | |
106 | 'virtioscsi6' => { bus => 3, addr => 7 }, | |
107 | 'virtioscsi7' => { bus => 3, addr => 8 }, | |
108 | 'virtioscsi8' => { bus => 3, addr => 9 }, | |
109 | 'virtioscsi9' => { bus => 3, addr => 10 }, | |
110 | 'virtioscsi10' => { bus => 3, addr => 11 }, | |
111 | 'virtioscsi11' => { bus => 3, addr => 12 }, | |
112 | 'virtioscsi12' => { bus => 3, addr => 13 }, | |
113 | 'virtioscsi13' => { bus => 3, addr => 14 }, | |
114 | 'virtioscsi14' => { bus => 3, addr => 15 }, | |
115 | 'virtioscsi15' => { bus => 3, addr => 16 }, | |
116 | 'virtioscsi16' => { bus => 3, addr => 17 }, | |
117 | 'virtioscsi17' => { bus => 3, addr => 18 }, | |
118 | 'virtioscsi18' => { bus => 3, addr => 19 }, | |
119 | 'virtioscsi19' => { bus => 3, addr => 20 }, | |
120 | 'virtioscsi20' => { bus => 3, addr => 21 }, | |
121 | 'virtioscsi21' => { bus => 3, addr => 22 }, | |
122 | 'virtioscsi22' => { bus => 3, addr => 23 }, | |
123 | 'virtioscsi23' => { bus => 3, addr => 24 }, | |
124 | 'virtioscsi24' => { bus => 3, addr => 25 }, | |
125 | 'virtioscsi25' => { bus => 3, addr => 26 }, | |
126 | 'virtioscsi26' => { bus => 3, addr => 27 }, | |
127 | 'virtioscsi27' => { bus => 3, addr => 28 }, | |
128 | 'virtioscsi28' => { bus => 3, addr => 29 }, | |
129 | 'virtioscsi29' => { bus => 3, addr => 30 }, | |
130 | 'virtioscsi30' => { bus => 3, addr => 31 }, | |
2513b862 DC |
131 | 'scsihw2' => { bus => 4, addr => 1 }, |
132 | 'scsihw3' => { bus => 4, addr => 2 }, | |
133 | 'scsihw4' => { bus => 4, addr => 3 }, | |
d7d698f6 TL |
134 | } if !defined($pci_addr_map); |
135 | return $pci_addr_map; | |
136 | } | |
137 | ||
138 | my $get_addr_mapping_from_id = sub { | |
139 | my ($map, $id) = @_; | |
140 | ||
141 | my $d = $map->{$id}; | |
142 | return undef if !defined($d) || !defined($d->{bus}) || !defined($d->{addr}); | |
143 | ||
144 | return { bus => $d->{bus}, addr => sprintf("0x%x", $d->{addr}) }; | |
de9768f0 DC |
145 | }; |
146 | ||
147 | sub print_pci_addr { | |
d559309f | 148 | my ($id, $bridges, $arch, $machine) = @_; |
de9768f0 DC |
149 | |
150 | my $res = ''; | |
151 | ||
d7d698f6 | 152 | # using same bus slots on all HW, so we need to check special cases here: |
d559309f WB |
153 | my $busname = 'pci'; |
154 | if ($arch eq 'aarch64' && $machine =~ /^virt/) { | |
d7d698f6 | 155 | die "aarch64/virt cannot use IDE devices\n" if $id =~ /^ide/; |
d559309f WB |
156 | $busname = 'pcie'; |
157 | } | |
158 | ||
d7d698f6 TL |
159 | my $map = get_pci_addr_map(); |
160 | if (my $d = $get_addr_mapping_from_id->($map, $id)) { | |
161 | $res = ",bus=$busname.$d->{bus},addr=$d->{addr}"; | |
162 | $bridges->{$d->{bus}} = 1 if $bridges; | |
de9768f0 | 163 | } |
de9768f0 | 164 | |
d7d698f6 | 165 | return $res; |
de9768f0 DC |
166 | } |
167 | ||
d7d698f6 TL |
168 | my $pcie_addr_map; |
169 | sub get_pcie_addr_map { | |
170 | $pcie_addr_map = { | |
55655ebc | 171 | vga => { bus => 'pcie.0', addr => 1 }, |
de9768f0 DC |
172 | hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 }, |
173 | hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 }, | |
174 | hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 }, | |
175 | hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 }, | |
c4e16381 AL |
176 | hostpci4 => { bus => "ich9-pcie-port-5", addr => 0 }, |
177 | hostpci5 => { bus => "ich9-pcie-port-6", addr => 0 }, | |
178 | hostpci6 => { bus => "ich9-pcie-port-7", addr => 0 }, | |
179 | hostpci7 => { bus => "ich9-pcie-port-8", addr => 0 }, | |
180 | hostpci8 => { bus => "ich9-pcie-port-9", addr => 0 }, | |
181 | hostpci9 => { bus => "ich9-pcie-port-10", addr => 0 }, | |
182 | hostpci10 => { bus => "ich9-pcie-port-11", addr => 0 }, | |
183 | hostpci11 => { bus => "ich9-pcie-port-12", addr => 0 }, | |
184 | hostpci12 => { bus => "ich9-pcie-port-13", addr => 0 }, | |
185 | hostpci13 => { bus => "ich9-pcie-port-14", addr => 0 }, | |
186 | hostpci14 => { bus => "ich9-pcie-port-15", addr => 0 }, | |
187 | hostpci15 => { bus => "ich9-pcie-port-16", addr => 0 }, | |
739ba340 DC |
188 | # win7 is picky about pcie assignments |
189 | hostpci0bus0 => { bus => "pcie.0", addr => 16 }, | |
190 | hostpci1bus0 => { bus => "pcie.0", addr => 17 }, | |
191 | hostpci2bus0 => { bus => "pcie.0", addr => 18 }, | |
192 | hostpci3bus0 => { bus => "pcie.0", addr => 19 }, | |
6dbcb073 | 193 | ivshmem => { bus => 'pcie.0', addr => 20 }, |
c4e16381 AL |
194 | hostpci4bus0 => { bus => "pcie.0", addr => 9 }, |
195 | hostpci5bus0 => { bus => "pcie.0", addr => 10 }, | |
196 | hostpci6bus0 => { bus => "pcie.0", addr => 11 }, | |
197 | hostpci7bus0 => { bus => "pcie.0", addr => 12 }, | |
198 | hostpci8bus0 => { bus => "pcie.0", addr => 13 }, | |
199 | hostpci9bus0 => { bus => "pcie.0", addr => 14 }, | |
200 | hostpci10bus0 => { bus => "pcie.0", addr => 15 }, | |
e2b0d85d TL |
201 | hostpci11bus0 => { bus => "pcie.0", addr => 21 }, |
202 | hostpci12bus0 => { bus => "pcie.0", addr => 22 }, | |
203 | hostpci13bus0 => { bus => "pcie.0", addr => 23 }, | |
204 | hostpci14bus0 => { bus => "pcie.0", addr => 24 }, | |
205 | hostpci15bus0 => { bus => "pcie.0", addr => 25 }, | |
d7d698f6 TL |
206 | } if !defined($pcie_addr_map); |
207 | ||
208 | return $pcie_addr_map; | |
209 | } | |
210 | ||
211 | sub print_pcie_addr { | |
212 | my ($id) = @_; | |
213 | ||
214 | my $res = ''; | |
de9768f0 | 215 | |
d7d698f6 TL |
216 | my $map = get_pcie_addr_map($id); |
217 | if (my $d = $get_addr_mapping_from_id->($map, $id)) { | |
218 | $res = ",bus=$d->{bus},addr=$d->{addr}"; | |
de9768f0 | 219 | } |
de9768f0 | 220 | |
d7d698f6 | 221 | return $res; |
de9768f0 | 222 | } |
b71351a7 | 223 | |
c4e16381 AL |
224 | # Generates the device strings for additional pcie root ports. The first 4 pcie |
225 | # root ports are defined in the pve-q35*.cfg files. | |
226 | sub print_pcie_root_port { | |
227 | my ($i) = @_; | |
228 | my $res = ''; | |
229 | ||
c4e16381 | 230 | my $root_port_addresses = { |
e2b0d85d TL |
231 | 4 => "10.0", |
232 | 5 => "10.1", | |
233 | 6 => "10.2", | |
234 | 7 => "10.3", | |
235 | 8 => "10.4", | |
236 | 9 => "10.5", | |
c4e16381 AL |
237 | 10 => "10.6", |
238 | 11 => "10.7", | |
239 | 12 => "11.0", | |
240 | 13 => "11.1", | |
241 | 14 => "11.2", | |
242 | 15 => "11.3", | |
243 | }; | |
244 | ||
245 | if (defined($root_port_addresses->{$i})) { | |
e2b0d85d | 246 | my $id = $i + 1; |
c4e16381 AL |
247 | $res = "pcie-root-port,id=ich9-pcie-port-${id}"; |
248 | $res .= ",addr=$root_port_addresses->{$i}"; | |
249 | $res .= ",x-speed=16,x-width=32,multifunction=on,bus=pcie.0"; | |
250 | $res .= ",port=${id},chassis=${id}"; | |
251 | } | |
252 | ||
253 | return $res; | |
254 | } | |
255 | ||
b71351a7 | 256 | 1; |