1 /*
2 * SPAPR PHB emulation, RTAS interface to PCI config space, device tree nodes
3 * for enumerated devices.
4 *
5 * Borrowed heavily from QEMU's spapr_pci.c,
6 * Copyright (c) 2011 Alexey Kardashevskiy, IBM Corporation.
7 * Copyright (c) 2011 David Gibson, IBM Corporation.
8 *
9 * Modifications copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 as published
13 * by the Free Software Foundation.
14 */
15
16 #include "spapr.h"
17 #include "spapr_pci.h"
18 #include "kvm/devices.h"
19 #include "kvm/fdt.h"
20 #include "kvm/util.h"
21 #include "kvm/of_pci.h"
22 #include "kvm/pci.h"
23
24 #include <linux/pci_regs.h>
25 #include <linux/byteorder.h>
26
27
28 /* #define DEBUG_PHB yes */
29 #ifdef DEBUG_PHB
30 #define phb_dprintf(fmt, ...) \
31 do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
32 #else
33 #define phb_dprintf(fmt, ...) \
34 do { } while (0)
35 #endif
36
37 static const uint32_t bars[] = {
38 PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1,
39 PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3,
40 PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5
41 /*, PCI_ROM_ADDRESS*/
42 };
43
44 #define PCI_NUM_REGIONS 7
45
46 static struct spapr_phb phb;
47
rtas_ibm_read_pci_config(struct kvm_cpu * vcpu,uint32_t token,uint32_t nargs,target_ulong args,uint32_t nret,target_ulong rets)48 static void rtas_ibm_read_pci_config(struct kvm_cpu *vcpu,
49 uint32_t token, uint32_t nargs,
50 target_ulong args,
51 uint32_t nret, target_ulong rets)
52 {
53 uint32_t val = 0;
54 uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
55 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
56 struct pci_device_header *dev = pci__find_dev(addr.device_number);
57 uint32_t size = rtas_ld(vcpu->kvm, args, 3);
58
59 if (buid != phb.buid || !dev || (size > 4)) {
60 phb_dprintf("- cfgRd buid 0x%lx cfg addr 0x%x size %d not found\n",
61 buid, addr.w, size);
62
63 rtas_st(vcpu->kvm, rets, 0, -1);
64 return;
65 }
66 pci__config_rd(vcpu->kvm, addr, &val, size);
67 /* It appears this wants a byteswapped result... */
68 switch (size) {
69 case 4:
70 val = le32_to_cpu(val);
71 break;
72 case 2:
73 val = le16_to_cpu(val>>16);
74 break;
75 case 1:
76 val = val >> 24;
77 break;
78 }
79 phb_dprintf("- cfgRd buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
80 buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
81 addr.register_number, val);
82
83 rtas_st(vcpu->kvm, rets, 0, 0);
84 rtas_st(vcpu->kvm, rets, 1, val);
85 }
86
rtas_read_pci_config(struct kvm_cpu * vcpu,uint32_t token,uint32_t nargs,target_ulong args,uint32_t nret,target_ulong rets)87 static void rtas_read_pci_config(struct kvm_cpu *vcpu,
88 uint32_t token, uint32_t nargs,
89 target_ulong args,
90 uint32_t nret, target_ulong rets)
91 {
92 uint32_t val;
93 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
94 struct pci_device_header *dev = pci__find_dev(addr.device_number);
95 uint32_t size = rtas_ld(vcpu->kvm, args, 1);
96
97 if (!dev || (size > 4)) {
98 rtas_st(vcpu->kvm, rets, 0, -1);
99 return;
100 }
101 pci__config_rd(vcpu->kvm, addr, &val, size);
102 switch (size) {
103 case 4:
104 val = le32_to_cpu(val);
105 break;
106 case 2:
107 val = le16_to_cpu(val>>16); /* We're yuck-endian. */
108 break;
109 case 1:
110 val = val >> 24;
111 break;
112 }
113 phb_dprintf("- cfgRd addr 0x%x size %d, val 0x%x\n", addr.w, size, val);
114 rtas_st(vcpu->kvm, rets, 0, 0);
115 rtas_st(vcpu->kvm, rets, 1, val);
116 }
117
rtas_ibm_write_pci_config(struct kvm_cpu * vcpu,uint32_t token,uint32_t nargs,target_ulong args,uint32_t nret,target_ulong rets)118 static void rtas_ibm_write_pci_config(struct kvm_cpu *vcpu,
119 uint32_t token, uint32_t nargs,
120 target_ulong args,
121 uint32_t nret, target_ulong rets)
122 {
123 uint64_t buid = ((uint64_t)rtas_ld(vcpu->kvm, args, 1) << 32) | rtas_ld(vcpu->kvm, args, 2);
124 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
125 struct pci_device_header *dev = pci__find_dev(addr.device_number);
126 uint32_t size = rtas_ld(vcpu->kvm, args, 3);
127 uint32_t val = rtas_ld(vcpu->kvm, args, 4);
128
129 if (buid != phb.buid || !dev || (size > 4)) {
130 phb_dprintf("- cfgWr buid 0x%lx cfg addr 0x%x/%d error (val 0x%x)\n",
131 buid, addr.w, size, val);
132
133 rtas_st(vcpu->kvm, rets, 0, -1);
134 return;
135 }
136 phb_dprintf("- cfgWr buid 0x%lx addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
137 buid, addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
138 addr.register_number, val);
139 switch (size) {
140 case 4:
141 val = le32_to_cpu(val);
142 break;
143 case 2:
144 val = le16_to_cpu(val) << 16;
145 break;
146 case 1:
147 val = val >> 24;
148 break;
149 }
150 pci__config_wr(vcpu->kvm, addr, &val, size);
151 rtas_st(vcpu->kvm, rets, 0, 0);
152 }
153
rtas_write_pci_config(struct kvm_cpu * vcpu,uint32_t token,uint32_t nargs,target_ulong args,uint32_t nret,target_ulong rets)154 static void rtas_write_pci_config(struct kvm_cpu *vcpu,
155 uint32_t token, uint32_t nargs,
156 target_ulong args,
157 uint32_t nret, target_ulong rets)
158 {
159 union pci_config_address addr = { .w = rtas_ld(vcpu->kvm, args, 0) };
160 struct pci_device_header *dev = pci__find_dev(addr.device_number);
161 uint32_t size = rtas_ld(vcpu->kvm, args, 1);
162 uint32_t val = rtas_ld(vcpu->kvm, args, 2);
163
164 if (!dev || (size > 4)) {
165 rtas_st(vcpu->kvm, rets, 0, -1);
166 return;
167 }
168
169 phb_dprintf("- cfgWr addr 0x%x (/%d): b%d,d%d,f%d,r0x%x, val 0x%x\n",
170 addr.w, size, addr.bus_number, addr.device_number, addr.function_number,
171 addr.register_number, val);
172 switch (size) {
173 case 4:
174 val = le32_to_cpu(val);
175 break;
176 case 2:
177 val = le16_to_cpu(val) << 16;
178 break;
179 case 1:
180 val = val >> 24;
181 break;
182 }
183 pci__config_wr(vcpu->kvm, addr, &val, size);
184 rtas_st(vcpu->kvm, rets, 0, 0);
185 }
186
spapr_create_phb(struct kvm * kvm,const char * busname,uint64_t buid,uint64_t mem_win_addr,uint64_t mem_win_size,uint64_t io_win_addr,uint64_t io_win_size)187 void spapr_create_phb(struct kvm *kvm,
188 const char *busname, uint64_t buid,
189 uint64_t mem_win_addr, uint64_t mem_win_size,
190 uint64_t io_win_addr, uint64_t io_win_size)
191 {
192 /*
193 * Since kvmtool doesn't really have any concept of buses etc.,
194 * there's nothing to register here. Just register RTAS.
195 */
196 spapr_rtas_register("read-pci-config", rtas_read_pci_config);
197 spapr_rtas_register("write-pci-config", rtas_write_pci_config);
198 spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config);
199 spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config);
200
201 phb.buid = buid;
202 phb.mem_addr = mem_win_addr;
203 phb.mem_size = mem_win_size;
204 phb.io_addr = io_win_addr;
205 phb.io_size = io_win_size;
206
207 kvm->arch.phb = &phb;
208 }
209
bar_to_ss(unsigned long bar)210 static uint32_t bar_to_ss(unsigned long bar)
211 {
212 if ((bar & PCI_BASE_ADDRESS_SPACE) ==
213 PCI_BASE_ADDRESS_SPACE_IO)
214 return OF_PCI_SS_IO;
215 else if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64)
216 return OF_PCI_SS_M64;
217 else
218 return OF_PCI_SS_M32;
219 }
220
bar_to_addr(unsigned long bar)221 static unsigned long bar_to_addr(unsigned long bar)
222 {
223 if ((bar & PCI_BASE_ADDRESS_SPACE) ==
224 PCI_BASE_ADDRESS_SPACE_IO)
225 return bar & PCI_BASE_ADDRESS_IO_MASK;
226 else
227 return bar & PCI_BASE_ADDRESS_MEM_MASK;
228 }
229
spapr_populate_pci_devices(struct kvm * kvm,uint32_t xics_phandle,void * fdt)230 int spapr_populate_pci_devices(struct kvm *kvm,
231 uint32_t xics_phandle,
232 void *fdt)
233 {
234 int bus_off, node_off = 0, devid, fn, i, n, devices;
235 struct device_header *dev_hdr;
236 char nodename[256];
237 struct of_pci_unit64_address {
238 u32 phys_hi;
239 u64 addr;
240 u64 size;
241 } __attribute((packed)) reg[PCI_NUM_REGIONS + 1], assigned_addresses[PCI_NUM_REGIONS];
242 uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
243 struct of_pci_ranges_entry ranges[] = {
244 {
245 {
246 cpu_to_be32(of_pci_b_ss(1)),
247 cpu_to_be32(0),
248 cpu_to_be32(0),
249 },
250 cpu_to_be64(phb.io_addr),
251 cpu_to_be64(phb.io_size),
252 },
253 {
254 {
255 cpu_to_be32(of_pci_b_ss(2)),
256 cpu_to_be32(0),
257 cpu_to_be32(0),
258 },
259 cpu_to_be64(phb.mem_addr),
260 cpu_to_be64(phb.mem_size),
261 },
262 };
263 uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 };
264 uint32_t interrupt_map_mask[] = {
265 cpu_to_be32(of_pci_b_ddddd(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0};
266 uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7];
267
268 /* Start populating the FDT */
269 sprintf(nodename, "pci@%" PRIx64, phb.buid);
270 bus_off = fdt_add_subnode(fdt, 0, nodename);
271 if (bus_off < 0) {
272 die("error making bus subnode, %s\n", fdt_strerror(bus_off));
273 return bus_off;
274 }
275
276 /* Write PHB properties */
277 _FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));
278 _FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));
279 _FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));
280 _FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));
281 _FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
282 _FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
283 _FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
284 _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));
285 _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
286 _FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",
287 &interrupt_map_mask, sizeof(interrupt_map_mask)));
288
289 /* Populate PCI devices and allocate IRQs */
290 devices = 0;
291 dev_hdr = device__first_dev(DEVICE_BUS_PCI);
292 while (dev_hdr) {
293 uint32_t *irqmap = interrupt_map[devices];
294 struct pci_device_header *hdr = dev_hdr->data;
295
296 if (!hdr)
297 continue;
298
299 devid = dev_hdr->dev_num;
300 fn = 0; /* kvmtool doesn't yet do multifunction devices */
301
302 sprintf(nodename, "pci@%u,%u", devid, fn);
303
304 /* Allocate interrupt from the map */
305 if (devid > SPAPR_PCI_NUM_LSI) {
306 die("Unexpected behaviour in spapr_populate_pci_devices,"
307 "wrong devid %u\n", devid);
308 }
309 irqmap[0] = cpu_to_be32(of_pci_b_ddddd(devid)|of_pci_b_fff(fn));
310 irqmap[1] = 0;
311 irqmap[2] = 0;
312 irqmap[3] = 0;
313 irqmap[4] = cpu_to_be32(xics_phandle);
314 /*
315 * This is nasty; the PCI devs are set up such that their own
316 * header's irq_line indicates the direct XICS IRQ number to
317 * use. There REALLY needs to be a hierarchical system in place
318 * to 'raise' an IRQ on the bridge which indexes/looks up which
319 * XICS IRQ to fire.
320 */
321 irqmap[5] = cpu_to_be32(hdr->irq_line);
322 irqmap[6] = cpu_to_be32(0x8);
323
324 /* Add node to FDT */
325 node_off = fdt_add_subnode(fdt, bus_off, nodename);
326 if (node_off < 0) {
327 die("error making node subnode, %s\n", fdt_strerror(bus_off));
328 return node_off;
329 }
330
331 _FDT(fdt_setprop_cell(fdt, node_off, "vendor-id",
332 le16_to_cpu(hdr->vendor_id)));
333 _FDT(fdt_setprop_cell(fdt, node_off, "device-id",
334 le16_to_cpu(hdr->device_id)));
335 _FDT(fdt_setprop_cell(fdt, node_off, "revision-id",
336 hdr->revision_id));
337 _FDT(fdt_setprop_cell(fdt, node_off, "class-code",
338 hdr->class[0] | (hdr->class[1] << 8) | (hdr->class[2] << 16)));
339 _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id",
340 le16_to_cpu(hdr->subsys_id)));
341 _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id",
342 le16_to_cpu(hdr->subsys_vendor_id)));
343
344 /* Config space region comes first */
345 reg[0].phys_hi = cpu_to_be32(
346 of_pci_b_n(0) |
347 of_pci_b_p(0) |
348 of_pci_b_t(0) |
349 of_pci_b_ss(OF_PCI_SS_CONFIG) |
350 of_pci_b_bbbbbbbb(0) |
351 of_pci_b_ddddd(devid) |
352 of_pci_b_fff(fn));
353 reg[0].addr = 0;
354 reg[0].size = 0;
355
356 n = 0;
357 /* Six BARs, no ROM supported, addresses are 32bit */
358 for (i = 0; i < 6; ++i) {
359 if (0 == hdr->bar[i]) {
360 continue;
361 }
362
363 reg[n+1].phys_hi = cpu_to_be32(
364 of_pci_b_n(0) |
365 of_pci_b_p(0) |
366 of_pci_b_t(0) |
367 of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
368 of_pci_b_bbbbbbbb(0) |
369 of_pci_b_ddddd(devid) |
370 of_pci_b_fff(fn) |
371 of_pci_b_rrrrrrrr(bars[i]));
372 reg[n+1].size = cpu_to_be64(pci__bar_size(hdr, i));
373 reg[n+1].addr = 0;
374
375 assigned_addresses[n].phys_hi = cpu_to_be32(
376 of_pci_b_n(1) |
377 of_pci_b_p(0) |
378 of_pci_b_t(0) |
379 of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
380 of_pci_b_bbbbbbbb(0) |
381 of_pci_b_ddddd(devid) |
382 of_pci_b_fff(fn) |
383 of_pci_b_rrrrrrrr(bars[i]));
384
385 /*
386 * Writing zeroes to assigned_addresses causes the guest kernel to
387 * reassign BARs
388 */
389 assigned_addresses[n].addr = cpu_to_be64(bar_to_addr(le32_to_cpu(hdr->bar[i])));
390 assigned_addresses[n].size = reg[n+1].size;
391
392 ++n;
393 }
394 _FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1)));
395 _FDT(fdt_setprop(fdt, node_off, "assigned-addresses",
396 assigned_addresses,
397 sizeof(assigned_addresses[0])*(n)));
398 _FDT(fdt_setprop_cell(fdt, node_off, "interrupts",
399 hdr->irq_pin));
400
401 /* We don't set ibm,dma-window property as we don't have an IOMMU. */
402
403 ++devices;
404 dev_hdr = device__next_dev(dev_hdr);
405 }
406
407 /* Write interrupt map */
408 _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
409 devices * sizeof(interrupt_map[0])));
410
411 return 0;
412 }
413