xref: /kvmtool/powerpc/spapr_pci.c (revision 6606883c7d50b8eaa119459ee6a0a8b1698fc563)
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 
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 
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 
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 
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 
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 
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 
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 
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_unit_address reg[PCI_NUM_REGIONS + 1],
238 				   assigned_addresses[PCI_NUM_REGIONS];
239 	uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
240 	struct of_pci_ranges_entry ranges[] = {
241 		{
242 			{
243 				cpu_to_be32(of_pci_b_ss(1)),
244 				cpu_to_be32(0),
245 				cpu_to_be32(0),
246 			},
247 			cpu_to_be64(phb.io_addr),
248 			cpu_to_be64(phb.io_size),
249 		},
250 		{
251 			{
252 				cpu_to_be32(of_pci_b_ss(2)),
253 				cpu_to_be32(0),
254 				cpu_to_be32(0),
255 			},
256 			cpu_to_be64(phb.mem_addr),
257 			cpu_to_be64(phb.mem_size),
258 		},
259 	};
260 	uint64_t bus_reg[] = { cpu_to_be64(phb.buid), 0 };
261 	uint32_t interrupt_map_mask[] = {
262 		cpu_to_be32(of_pci_b_ddddd(-1)|of_pci_b_fff(-1)), 0x0, 0x0, 0x0};
263 	uint32_t interrupt_map[SPAPR_PCI_NUM_LSI][7];
264 
265 	/* Start populating the FDT */
266 	sprintf(nodename, "pci@%" PRIx64, phb.buid);
267 	bus_off = fdt_add_subnode(fdt, 0, nodename);
268 	if (bus_off < 0) {
269 		die("error making bus subnode, %s\n", fdt_strerror(bus_off));
270 		return bus_off;
271 	}
272 
273 	/* Write PHB properties */
274 	_FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));
275 	_FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));
276 	_FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));
277 	_FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));
278 	_FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
279 	_FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
280 	_FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
281 	_FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));
282 	_FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
283 	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",
284 			 &interrupt_map_mask, sizeof(interrupt_map_mask)));
285 
286 	/* Populate PCI devices and allocate IRQs */
287 	devices = 0;
288 	dev_hdr = device__first_dev(DEVICE_BUS_PCI);
289 	while (dev_hdr) {
290 		uint32_t *irqmap = interrupt_map[devices];
291 		struct pci_device_header *hdr = dev_hdr->data;
292 
293 		if (!hdr)
294 			continue;
295 
296 		devid = dev_hdr->dev_num;
297 		fn = 0; /* kvmtool doesn't yet do multifunction devices */
298 
299 		sprintf(nodename, "pci@%u,%u", devid, fn);
300 
301 		/* Allocate interrupt from the map */
302 		if (devid > SPAPR_PCI_NUM_LSI)	{
303 			die("Unexpected behaviour in spapr_populate_pci_devices,"
304 			    "wrong devid %u\n", devid);
305 		}
306 		irqmap[0] = cpu_to_be32(of_pci_b_ddddd(devid)|of_pci_b_fff(fn));
307 		irqmap[1] = 0;
308 		irqmap[2] = 0;
309 		irqmap[3] = 0;
310 		irqmap[4] = cpu_to_be32(xics_phandle);
311 		/*
312 		 * This is nasty; the PCI devs are set up such that their own
313 		 * header's irq_line indicates the direct XICS IRQ number to
314 		 * use.  There REALLY needs to be a hierarchical system in place
315 		 * to 'raise' an IRQ on the bridge which indexes/looks up which
316 		 * XICS IRQ to fire.
317 		 */
318 		irqmap[5] = cpu_to_be32(hdr->irq_line);
319 		irqmap[6] = cpu_to_be32(0x8);
320 
321 		/* Add node to FDT */
322 		node_off = fdt_add_subnode(fdt, bus_off, nodename);
323 		if (node_off < 0) {
324 			die("error making node subnode, %s\n", fdt_strerror(bus_off));
325 			return node_off;
326 		}
327 
328 		_FDT(fdt_setprop_cell(fdt, node_off, "vendor-id",
329 				      le16_to_cpu(hdr->vendor_id)));
330 		_FDT(fdt_setprop_cell(fdt, node_off, "device-id",
331 				      le16_to_cpu(hdr->device_id)));
332 		_FDT(fdt_setprop_cell(fdt, node_off, "revision-id",
333 				      hdr->revision_id));
334 		_FDT(fdt_setprop_cell(fdt, node_off, "class-code",
335 				      hdr->class[0] | (hdr->class[1] << 8) | (hdr->class[2] << 16)));
336 		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id",
337 				      le16_to_cpu(hdr->subsys_id)));
338 		_FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id",
339 				      le16_to_cpu(hdr->subsys_vendor_id)));
340 
341 		/* Config space region comes first */
342 		reg[0].hi = cpu_to_be32(
343 			of_pci_b_n(0) |
344 			of_pci_b_p(0) |
345 			of_pci_b_t(0) |
346 			of_pci_b_ss(OF_PCI_SS_CONFIG) |
347 			of_pci_b_bbbbbbbb(0) |
348 			of_pci_b_ddddd(devid) |
349 			of_pci_b_fff(fn));
350 		reg[0].mid = 0;
351 		reg[0].lo = 0;
352 
353 		n = 0;
354 		/* Six BARs, no ROM supported, addresses are 32bit */
355 		for (i = 0; i < 6; ++i) {
356 			if (0 == hdr->bar[i]) {
357 				continue;
358 			}
359 
360 			reg[n+1].hi = cpu_to_be32(
361 				of_pci_b_n(0) |
362 				of_pci_b_p(0) |
363 				of_pci_b_t(0) |
364 				of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
365 				of_pci_b_bbbbbbbb(0) |
366 				of_pci_b_ddddd(devid) |
367 				of_pci_b_fff(fn) |
368 				of_pci_b_rrrrrrrr(bars[i]));
369 			reg[n+1].mid = 0;
370 			reg[n+1].lo = cpu_to_be64(hdr->bar_size[i]);
371 
372 			assigned_addresses[n].hi = cpu_to_be32(
373 				of_pci_b_n(1) |
374 				of_pci_b_p(0) |
375 				of_pci_b_t(0) |
376 				of_pci_b_ss(bar_to_ss(le32_to_cpu(hdr->bar[i]))) |
377 				of_pci_b_bbbbbbbb(0) |
378 				of_pci_b_ddddd(devid) |
379 				of_pci_b_fff(fn) |
380 				of_pci_b_rrrrrrrr(bars[i]));
381 
382 			/*
383 			 * Writing zeroes to assigned_addresses causes the guest kernel to
384 			 * reassign BARs
385 			 */
386 			assigned_addresses[n].mid = cpu_to_be64(bar_to_addr(le32_to_cpu(hdr->bar[i])));
387 			assigned_addresses[n].lo = reg[n+1].lo;
388 
389 			++n;
390 		}
391 		_FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1)));
392 		_FDT(fdt_setprop(fdt, node_off, "assigned-addresses",
393 				 assigned_addresses,
394 				 sizeof(assigned_addresses[0])*(n)));
395 		_FDT(fdt_setprop_cell(fdt, node_off, "interrupts",
396 				      hdr->irq_pin));
397 
398 		/* We don't set ibm,dma-window property as we don't have an IOMMU. */
399 
400 		++devices;
401 		dev_hdr = device__next_dev(dev_hdr);
402 	}
403 
404 	/* Write interrupt map */
405 	_FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,
406 			 devices * sizeof(interrupt_map[0])));
407 
408 	return 0;
409 }
410