]> git.proxmox.com Git - qemu-server.git/blame - PVE/QemuServer/PCI.pm
move the vmgenid device after readconfig on q35
[qemu-server.git] / PVE / QemuServer / PCI.pm
CommitLineData
de9768f0
DC
1package PVE::QemuServer::PCI;
2
3use base 'Exporter';
4
5our @EXPORT_OK = qw(
6print_pci_addr
7print_pcie_addr
c4e16381 8print_pcie_root_port
de9768f0
DC
9);
10
d7d698f6
TL
11my $pci_addr_map;
12sub 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 },
74 'virtio6' => { bus => 2, addr => 1 },
75 'virtio7' => { bus => 2, addr => 2 },
76 'virtio8' => { bus => 2, addr => 3 },
77 'virtio9' => { bus => 2, addr => 4 },
78 'virtio10' => { bus => 2, addr => 5 },
79 'virtio11' => { bus => 2, addr => 6 },
80 'virtio12' => { bus => 2, addr => 7 },
81 'virtio13' => { bus => 2, addr => 8 },
82 'virtio14' => { bus => 2, addr => 9 },
83 'virtio15' => { bus => 2, addr => 10 },
84 'ivshmem' => { bus => 2, addr => 11 },
85 'audio0' => { bus => 2, addr => 12 },
86 hostpci4 => { bus => 2, addr => 13 },
87 hostpci5 => { bus => 2, addr => 14 },
88 hostpci6 => { bus => 2, addr => 15 },
89 hostpci7 => { bus => 2, addr => 16 },
90 hostpci8 => { bus => 2, addr => 17 },
91 hostpci9 => { bus => 2, addr => 18 },
92 hostpci10 => { bus => 2, addr => 19 },
93 hostpci11 => { bus => 2, addr => 20 },
94 hostpci12 => { bus => 2, addr => 21 },
95 hostpci13 => { bus => 2, addr => 22 },
96 hostpci14 => { bus => 2, addr => 23 },
97 hostpci15 => { bus => 2, addr => 24 },
98 'virtioscsi0' => { bus => 3, addr => 1 },
99 'virtioscsi1' => { bus => 3, addr => 2 },
100 'virtioscsi2' => { bus => 3, addr => 3 },
101 'virtioscsi3' => { bus => 3, addr => 4 },
102 'virtioscsi4' => { bus => 3, addr => 5 },
103 'virtioscsi5' => { bus => 3, addr => 6 },
104 'virtioscsi6' => { bus => 3, addr => 7 },
105 'virtioscsi7' => { bus => 3, addr => 8 },
106 'virtioscsi8' => { bus => 3, addr => 9 },
107 'virtioscsi9' => { bus => 3, addr => 10 },
108 'virtioscsi10' => { bus => 3, addr => 11 },
109 'virtioscsi11' => { bus => 3, addr => 12 },
110 'virtioscsi12' => { bus => 3, addr => 13 },
111 'virtioscsi13' => { bus => 3, addr => 14 },
112 'virtioscsi14' => { bus => 3, addr => 15 },
113 'virtioscsi15' => { bus => 3, addr => 16 },
114 'virtioscsi16' => { bus => 3, addr => 17 },
115 'virtioscsi17' => { bus => 3, addr => 18 },
116 'virtioscsi18' => { bus => 3, addr => 19 },
117 'virtioscsi19' => { bus => 3, addr => 20 },
118 'virtioscsi20' => { bus => 3, addr => 21 },
119 'virtioscsi21' => { bus => 3, addr => 22 },
120 'virtioscsi22' => { bus => 3, addr => 23 },
121 'virtioscsi23' => { bus => 3, addr => 24 },
122 'virtioscsi24' => { bus => 3, addr => 25 },
123 'virtioscsi25' => { bus => 3, addr => 26 },
124 'virtioscsi26' => { bus => 3, addr => 27 },
125 'virtioscsi27' => { bus => 3, addr => 28 },
126 'virtioscsi28' => { bus => 3, addr => 29 },
127 'virtioscsi29' => { bus => 3, addr => 30 },
128 'virtioscsi30' => { bus => 3, addr => 31 },
129 } if !defined($pci_addr_map);
130 return $pci_addr_map;
131}
132
133my $get_addr_mapping_from_id = sub {
134 my ($map, $id) = @_;
135
136 my $d = $map->{$id};
137 return undef if !defined($d) || !defined($d->{bus}) || !defined($d->{addr});
138
139 return { bus => $d->{bus}, addr => sprintf("0x%x", $d->{addr}) };
de9768f0
DC
140};
141
142sub print_pci_addr {
d559309f 143 my ($id, $bridges, $arch, $machine) = @_;
de9768f0
DC
144
145 my $res = '';
146
d7d698f6 147 # using same bus slots on all HW, so we need to check special cases here:
d559309f
WB
148 my $busname = 'pci';
149 if ($arch eq 'aarch64' && $machine =~ /^virt/) {
d7d698f6 150 die "aarch64/virt cannot use IDE devices\n" if $id =~ /^ide/;
d559309f
WB
151 $busname = 'pcie';
152 }
153
d7d698f6
TL
154 my $map = get_pci_addr_map();
155 if (my $d = $get_addr_mapping_from_id->($map, $id)) {
156 $res = ",bus=$busname.$d->{bus},addr=$d->{addr}";
157 $bridges->{$d->{bus}} = 1 if $bridges;
de9768f0 158 }
de9768f0 159
d7d698f6 160 return $res;
de9768f0
DC
161}
162
d7d698f6
TL
163my $pcie_addr_map;
164sub get_pcie_addr_map {
165 $pcie_addr_map = {
55655ebc 166 vga => { bus => 'pcie.0', addr => 1 },
de9768f0
DC
167 hostpci0 => { bus => "ich9-pcie-port-1", addr => 0 },
168 hostpci1 => { bus => "ich9-pcie-port-2", addr => 0 },
169 hostpci2 => { bus => "ich9-pcie-port-3", addr => 0 },
170 hostpci3 => { bus => "ich9-pcie-port-4", addr => 0 },
c4e16381
AL
171 hostpci4 => { bus => "ich9-pcie-port-5", addr => 0 },
172 hostpci5 => { bus => "ich9-pcie-port-6", addr => 0 },
173 hostpci6 => { bus => "ich9-pcie-port-7", addr => 0 },
174 hostpci7 => { bus => "ich9-pcie-port-8", addr => 0 },
175 hostpci8 => { bus => "ich9-pcie-port-9", addr => 0 },
176 hostpci9 => { bus => "ich9-pcie-port-10", addr => 0 },
177 hostpci10 => { bus => "ich9-pcie-port-11", addr => 0 },
178 hostpci11 => { bus => "ich9-pcie-port-12", addr => 0 },
179 hostpci12 => { bus => "ich9-pcie-port-13", addr => 0 },
180 hostpci13 => { bus => "ich9-pcie-port-14", addr => 0 },
181 hostpci14 => { bus => "ich9-pcie-port-15", addr => 0 },
182 hostpci15 => { bus => "ich9-pcie-port-16", addr => 0 },
739ba340
DC
183 # win7 is picky about pcie assignments
184 hostpci0bus0 => { bus => "pcie.0", addr => 16 },
185 hostpci1bus0 => { bus => "pcie.0", addr => 17 },
186 hostpci2bus0 => { bus => "pcie.0", addr => 18 },
187 hostpci3bus0 => { bus => "pcie.0", addr => 19 },
6dbcb073 188 ivshmem => { bus => 'pcie.0', addr => 20 },
c4e16381
AL
189 hostpci4bus0 => { bus => "pcie.0", addr => 9 },
190 hostpci5bus0 => { bus => "pcie.0", addr => 10 },
191 hostpci6bus0 => { bus => "pcie.0", addr => 11 },
192 hostpci7bus0 => { bus => "pcie.0", addr => 12 },
193 hostpci8bus0 => { bus => "pcie.0", addr => 13 },
194 hostpci9bus0 => { bus => "pcie.0", addr => 14 },
195 hostpci10bus0 => { bus => "pcie.0", addr => 15 },
e2b0d85d
TL
196 hostpci11bus0 => { bus => "pcie.0", addr => 21 },
197 hostpci12bus0 => { bus => "pcie.0", addr => 22 },
198 hostpci13bus0 => { bus => "pcie.0", addr => 23 },
199 hostpci14bus0 => { bus => "pcie.0", addr => 24 },
200 hostpci15bus0 => { bus => "pcie.0", addr => 25 },
d7d698f6
TL
201 } if !defined($pcie_addr_map);
202
203 return $pcie_addr_map;
204}
205
206sub print_pcie_addr {
207 my ($id) = @_;
208
209 my $res = '';
de9768f0 210
d7d698f6
TL
211 my $map = get_pcie_addr_map($id);
212 if (my $d = $get_addr_mapping_from_id->($map, $id)) {
213 $res = ",bus=$d->{bus},addr=$d->{addr}";
de9768f0 214 }
de9768f0 215
d7d698f6 216 return $res;
de9768f0 217}
b71351a7 218
c4e16381
AL
219# Generates the device strings for additional pcie root ports. The first 4 pcie
220# root ports are defined in the pve-q35*.cfg files.
221sub print_pcie_root_port {
222 my ($i) = @_;
223 my $res = '';
224
c4e16381 225 my $root_port_addresses = {
e2b0d85d
TL
226 4 => "10.0",
227 5 => "10.1",
228 6 => "10.2",
229 7 => "10.3",
230 8 => "10.4",
231 9 => "10.5",
c4e16381
AL
232 10 => "10.6",
233 11 => "10.7",
234 12 => "11.0",
235 13 => "11.1",
236 14 => "11.2",
237 15 => "11.3",
238 };
239
240 if (defined($root_port_addresses->{$i})) {
e2b0d85d 241 my $id = $i + 1;
c4e16381
AL
242 $res = "pcie-root-port,id=ich9-pcie-port-${id}";
243 $res .= ",addr=$root_port_addresses->{$i}";
244 $res .= ",x-speed=16,x-width=32,multifunction=on,bus=pcie.0";
245 $res .= ",port=${id},chassis=${id}";
246 }
247
248 return $res;
249}
250
b71351a7 2511;