Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * Support routines for initializing a PCI subsystem
4 : : *
5 : : * Extruded from code written by
6 : : * Dave Rusling (david.rusling@reo.mts.dec.com)
7 : : * David Mosberger (davidm@cs.arizona.edu)
8 : : * David Miller (davem@redhat.com)
9 : : *
10 : : * Fixed for multiple PCI buses, 1999 Andrea Arcangeli <andrea@suse.de>
11 : : *
12 : : * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
13 : : * Resource sorting
14 : : */
15 : :
16 : : #include <linux/kernel.h>
17 : : #include <linux/export.h>
18 : : #include <linux/pci.h>
19 : : #include <linux/errno.h>
20 : : #include <linux/ioport.h>
21 : : #include <linux/cache.h>
22 : : #include <linux/slab.h>
23 : : #include "pci.h"
24 : :
25 : 0 : static void pci_std_update_resource(struct pci_dev *dev, int resno)
26 : : {
27 : 0 : struct pci_bus_region region;
28 : 0 : bool disable;
29 : 0 : u16 cmd;
30 : 0 : u32 new, check, mask;
31 : 0 : int reg;
32 : 0 : struct resource *res = dev->resource + resno;
33 : :
34 : : /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
35 [ # # ]: 0 : if (dev->is_virtfn)
36 : 0 : return;
37 : :
38 : : /*
39 : : * Ignore resources for unimplemented BARs and unused resource slots
40 : : * for 64 bit BARs.
41 : : */
42 [ # # ]: 0 : if (!res->flags)
43 : : return;
44 : :
45 [ # # ]: 0 : if (res->flags & IORESOURCE_UNSET)
46 : : return;
47 : :
48 : : /*
49 : : * Ignore non-moveable resources. This might be legacy resources for
50 : : * which no functional BAR register exists or another important
51 : : * system resource we shouldn't move around.
52 : : */
53 [ # # ]: 0 : if (res->flags & IORESOURCE_PCI_FIXED)
54 : : return;
55 : :
56 : 0 : pcibios_resource_to_bus(dev->bus, ®ion, res);
57 : 0 : new = region.start;
58 : :
59 [ # # ]: 0 : if (res->flags & IORESOURCE_IO) {
60 : 0 : mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
61 : 0 : new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
62 [ # # ]: 0 : } else if (resno == PCI_ROM_RESOURCE) {
63 : : mask = PCI_ROM_ADDRESS_MASK;
64 : : } else {
65 : 0 : mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
66 : 0 : new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
67 : : }
68 : :
69 [ # # ]: 0 : if (resno < PCI_ROM_RESOURCE) {
70 : 0 : reg = PCI_BASE_ADDRESS_0 + 4 * resno;
71 [ # # ]: 0 : } else if (resno == PCI_ROM_RESOURCE) {
72 : :
73 : : /*
74 : : * Apparently some Matrox devices have ROM BARs that read
75 : : * as zero when disabled, so don't update ROM BARs unless
76 : : * they're enabled. See https://lkml.org/lkml/2005/8/30/138.
77 : : */
78 [ # # ]: 0 : if (!(res->flags & IORESOURCE_ROM_ENABLE))
79 : : return;
80 : :
81 : 0 : reg = dev->rom_base_reg;
82 : 0 : new |= PCI_ROM_ADDRESS_ENABLE;
83 : : } else
84 : : return;
85 : :
86 : : /*
87 : : * We can't update a 64-bit BAR atomically, so when possible,
88 : : * disable decoding so that a half-updated BAR won't conflict
89 : : * with another device.
90 : : */
91 [ # # # # ]: 0 : disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
92 [ # # ]: 0 : if (disable) {
93 : 0 : pci_read_config_word(dev, PCI_COMMAND, &cmd);
94 : 0 : pci_write_config_word(dev, PCI_COMMAND,
95 : 0 : cmd & ~PCI_COMMAND_MEMORY);
96 : : }
97 : :
98 : 0 : pci_write_config_dword(dev, reg, new);
99 : 0 : pci_read_config_dword(dev, reg, &check);
100 : :
101 [ # # ]: 0 : if ((new ^ check) & mask) {
102 : 0 : pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
103 : : resno, new, check);
104 : : }
105 : :
106 [ # # ]: 0 : if (res->flags & IORESOURCE_MEM_64) {
107 : 0 : new = region.start >> 16 >> 16;
108 : 0 : pci_write_config_dword(dev, reg + 4, new);
109 : 0 : pci_read_config_dword(dev, reg + 4, &check);
110 [ # # ]: 0 : if (check != new) {
111 : 0 : pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
112 : : resno, new, check);
113 : : }
114 : : }
115 : :
116 [ # # ]: 0 : if (disable)
117 : 0 : pci_write_config_word(dev, PCI_COMMAND, cmd);
118 : : }
119 : :
120 : 0 : void pci_update_resource(struct pci_dev *dev, int resno)
121 : : {
122 [ # # ]: 0 : if (resno <= PCI_ROM_RESOURCE)
123 : 0 : pci_std_update_resource(dev, resno);
124 : : #ifdef CONFIG_PCI_IOV
125 : : else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
126 : : pci_iov_update_resource(dev, resno);
127 : : #endif
128 : 0 : }
129 : :
130 : 252 : int pci_claim_resource(struct pci_dev *dev, int resource)
131 : : {
132 : 252 : struct resource *res = &dev->resource[resource];
133 : 252 : struct resource *root, *conflict;
134 : :
135 [ - + ]: 252 : if (res->flags & IORESOURCE_UNSET) {
136 : 0 : pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
137 : : resource, res);
138 : 0 : return -EINVAL;
139 : : }
140 : :
141 : : /*
142 : : * If we have a shadow copy in RAM, the PCI device doesn't respond
143 : : * to the shadow range, so we don't need to claim it, and upstream
144 : : * bridges don't need to route the range to the device.
145 : : */
146 [ + - ]: 252 : if (res->flags & IORESOURCE_ROM_SHADOW)
147 : : return 0;
148 : :
149 : 252 : root = pci_find_parent_resource(dev, res);
150 [ - + ]: 252 : if (!root) {
151 : 0 : pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
152 : : resource, res);
153 : 0 : res->flags |= IORESOURCE_UNSET;
154 : 0 : return -EINVAL;
155 : : }
156 : :
157 : 252 : conflict = request_resource_conflict(root, res);
158 [ - + ]: 252 : if (conflict) {
159 : 0 : pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
160 : : resource, res, conflict->name, conflict);
161 : 0 : res->flags |= IORESOURCE_UNSET;
162 : 0 : return -EBUSY;
163 : : }
164 : :
165 : : return 0;
166 : : }
167 : : EXPORT_SYMBOL(pci_claim_resource);
168 : :
169 : 0 : void pci_disable_bridge_window(struct pci_dev *dev)
170 : : {
171 : : /* MMIO Base/Limit */
172 : 0 : pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
173 : :
174 : : /* Prefetchable MMIO Base/Limit */
175 : 0 : pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
176 : 0 : pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
177 : 0 : pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
178 : 0 : }
179 : :
180 : : /*
181 : : * Generic function that returns a value indicating that the device's
182 : : * original BIOS BAR address was not saved and so is not available for
183 : : * reinstatement.
184 : : *
185 : : * Can be over-ridden by architecture specific code that implements
186 : : * reinstatement functionality rather than leaving it disabled when
187 : : * normal allocation attempts fail.
188 : : */
189 : 0 : resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
190 : : {
191 : 0 : return 0;
192 : : }
193 : :
194 : 0 : static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
195 : : int resno, resource_size_t size)
196 : : {
197 : 0 : struct resource *root, *conflict;
198 : 0 : resource_size_t fw_addr, start, end;
199 : :
200 : 0 : fw_addr = pcibios_retrieve_fw_addr(dev, resno);
201 [ # # ]: 0 : if (!fw_addr)
202 : : return -ENOMEM;
203 : :
204 : 0 : start = res->start;
205 : 0 : end = res->end;
206 : 0 : res->start = fw_addr;
207 : 0 : res->end = res->start + size - 1;
208 : 0 : res->flags &= ~IORESOURCE_UNSET;
209 : :
210 : 0 : root = pci_find_parent_resource(dev, res);
211 [ # # ]: 0 : if (!root) {
212 [ # # ]: 0 : if (res->flags & IORESOURCE_IO)
213 : : root = &ioport_resource;
214 : : else
215 : 0 : root = &iomem_resource;
216 : : }
217 : :
218 : 0 : pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
219 : : resno, res);
220 : 0 : conflict = request_resource_conflict(root, res);
221 [ # # ]: 0 : if (conflict) {
222 : 0 : pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
223 : : resno, res, conflict->name, conflict);
224 : 0 : res->start = start;
225 : 0 : res->end = end;
226 : 0 : res->flags |= IORESOURCE_UNSET;
227 : 0 : return -EBUSY;
228 : : }
229 : : return 0;
230 : : }
231 : :
232 : : /*
233 : : * We don't have to worry about legacy ISA devices, so nothing to do here.
234 : : * This is marked as __weak because multiple architectures define it; it should
235 : : * eventually go away.
236 : : */
237 : 0 : resource_size_t __weak pcibios_align_resource(void *data,
238 : : const struct resource *res,
239 : : resource_size_t size,
240 : : resource_size_t align)
241 : : {
242 : 0 : return res->start;
243 : : }
244 : :
245 : 0 : static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
246 : : int resno, resource_size_t size, resource_size_t align)
247 : : {
248 : 0 : struct resource *res = dev->resource + resno;
249 : 0 : resource_size_t min;
250 : 0 : int ret;
251 : :
252 [ # # ]: 0 : min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
253 : :
254 : : /*
255 : : * First, try exact prefetching match. Even if a 64-bit
256 : : * prefetchable bridge window is below 4GB, we can't put a 32-bit
257 : : * prefetchable resource in it because pbus_size_mem() assumes a
258 : : * 64-bit window will contain no 32-bit resources. If we assign
259 : : * things differently than they were sized, not everything will fit.
260 : : */
261 : 0 : ret = pci_bus_alloc_resource(bus, res, size, align, min,
262 : : IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
263 : : pcibios_align_resource, dev);
264 [ # # ]: 0 : if (ret == 0)
265 : : return 0;
266 : :
267 : : /*
268 : : * If the prefetchable window is only 32 bits wide, we can put
269 : : * 64-bit prefetchable resources in it.
270 : : */
271 [ # # ]: 0 : if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
272 : : (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
273 : 0 : ret = pci_bus_alloc_resource(bus, res, size, align, min,
274 : : IORESOURCE_PREFETCH,
275 : : pcibios_align_resource, dev);
276 [ # # ]: 0 : if (ret == 0)
277 : : return 0;
278 : : }
279 : :
280 : : /*
281 : : * If we didn't find a better match, we can put any memory resource
282 : : * in a non-prefetchable window. If this resource is 32 bits and
283 : : * non-prefetchable, the first call already tried the only possibility
284 : : * so we don't need to try again.
285 : : */
286 [ # # ]: 0 : if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
287 : 0 : ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
288 : : pcibios_align_resource, dev);
289 : :
290 : : return ret;
291 : : }
292 : :
293 : 0 : static int _pci_assign_resource(struct pci_dev *dev, int resno,
294 : : resource_size_t size, resource_size_t min_align)
295 : : {
296 : 0 : struct pci_bus *bus;
297 : 0 : int ret;
298 : :
299 : 0 : bus = dev->bus;
300 [ # # ]: 0 : while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
301 [ # # # # ]: 0 : if (!bus->parent || !bus->self->transparent)
302 : : break;
303 : : bus = bus->parent;
304 : : }
305 : :
306 : 0 : return ret;
307 : : }
308 : :
309 : 0 : int pci_assign_resource(struct pci_dev *dev, int resno)
310 : : {
311 : 0 : struct resource *res = dev->resource + resno;
312 : 0 : resource_size_t align, size;
313 : 0 : int ret;
314 : :
315 [ # # ]: 0 : if (res->flags & IORESOURCE_PCI_FIXED)
316 : : return 0;
317 : :
318 : 0 : res->flags |= IORESOURCE_UNSET;
319 : 0 : align = pci_resource_alignment(dev, res);
320 [ # # ]: 0 : if (!align) {
321 : 0 : pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
322 : : resno, res);
323 : 0 : return -EINVAL;
324 : : }
325 : :
326 : 0 : size = resource_size(res);
327 : 0 : ret = _pci_assign_resource(dev, resno, size, align);
328 : :
329 : : /*
330 : : * If we failed to assign anything, let's try the address
331 : : * where firmware left it. That at least has a chance of
332 : : * working, which is better than just leaving it disabled.
333 : : */
334 [ # # ]: 0 : if (ret < 0) {
335 : 0 : pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
336 : 0 : ret = pci_revert_fw_address(res, dev, resno, size);
337 : : }
338 : :
339 [ # # ]: 0 : if (ret < 0) {
340 : 0 : pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
341 : 0 : return ret;
342 : : }
343 : :
344 : 0 : res->flags &= ~IORESOURCE_UNSET;
345 : 0 : res->flags &= ~IORESOURCE_STARTALIGN;
346 : 0 : pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
347 [ # # ]: 0 : if (resno < PCI_BRIDGE_RESOURCES)
348 : 0 : pci_update_resource(dev, resno);
349 : :
350 : : return 0;
351 : : }
352 : : EXPORT_SYMBOL(pci_assign_resource);
353 : :
354 : 0 : int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
355 : : resource_size_t min_align)
356 : : {
357 : 0 : struct resource *res = dev->resource + resno;
358 : 0 : unsigned long flags;
359 : 0 : resource_size_t new_size;
360 : 0 : int ret;
361 : :
362 [ # # ]: 0 : if (res->flags & IORESOURCE_PCI_FIXED)
363 : : return 0;
364 : :
365 : 0 : flags = res->flags;
366 : 0 : res->flags |= IORESOURCE_UNSET;
367 [ # # ]: 0 : if (!res->parent) {
368 : 0 : pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
369 : : resno, res);
370 : 0 : return -EINVAL;
371 : : }
372 : :
373 : : /* already aligned with min_align */
374 : 0 : new_size = resource_size(res) + addsize;
375 : 0 : ret = _pci_assign_resource(dev, resno, new_size, min_align);
376 [ # # ]: 0 : if (ret) {
377 : 0 : res->flags = flags;
378 : 0 : pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
379 : : resno, res, (unsigned long long) addsize);
380 : 0 : return ret;
381 : : }
382 : :
383 : 0 : res->flags &= ~IORESOURCE_UNSET;
384 : 0 : res->flags &= ~IORESOURCE_STARTALIGN;
385 : 0 : pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
386 : : resno, res, (unsigned long long) addsize);
387 [ # # ]: 0 : if (resno < PCI_BRIDGE_RESOURCES)
388 : 0 : pci_update_resource(dev, resno);
389 : :
390 : : return 0;
391 : : }
392 : :
393 : 0 : void pci_release_resource(struct pci_dev *dev, int resno)
394 : : {
395 : 0 : struct resource *res = dev->resource + resno;
396 : :
397 : 0 : pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
398 : :
399 [ # # ]: 0 : if (!res->parent)
400 : : return;
401 : :
402 : 0 : release_resource(res);
403 : 0 : res->end = resource_size(res) - 1;
404 : 0 : res->start = 0;
405 : 0 : res->flags |= IORESOURCE_UNSET;
406 : : }
407 : : EXPORT_SYMBOL(pci_release_resource);
408 : :
409 : 0 : int pci_resize_resource(struct pci_dev *dev, int resno, int size)
410 : : {
411 : 0 : struct resource *res = dev->resource + resno;
412 : 0 : int old, ret;
413 : 0 : u32 sizes;
414 : 0 : u16 cmd;
415 : :
416 : : /* Make sure the resource isn't assigned before resizing it. */
417 [ # # ]: 0 : if (!(res->flags & IORESOURCE_UNSET))
418 : : return -EBUSY;
419 : :
420 : 0 : pci_read_config_word(dev, PCI_COMMAND, &cmd);
421 [ # # ]: 0 : if (cmd & PCI_COMMAND_MEMORY)
422 : : return -EBUSY;
423 : :
424 : 0 : sizes = pci_rebar_get_possible_sizes(dev, resno);
425 [ # # ]: 0 : if (!sizes)
426 : : return -ENOTSUPP;
427 : :
428 [ # # ]: 0 : if (!(sizes & BIT(size)))
429 : : return -EINVAL;
430 : :
431 : 0 : old = pci_rebar_get_current_size(dev, resno);
432 [ # # ]: 0 : if (old < 0)
433 : : return old;
434 : :
435 : 0 : ret = pci_rebar_set_size(dev, resno, size);
436 [ # # ]: 0 : if (ret)
437 : : return ret;
438 : :
439 : 0 : res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
440 : :
441 : : /* Check if the new config works by trying to assign everything. */
442 : 0 : ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
443 [ # # ]: 0 : if (ret)
444 : 0 : goto error_resize;
445 : :
446 : : return 0;
447 : :
448 : : error_resize:
449 : 0 : pci_rebar_set_size(dev, resno, old);
450 : 0 : res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
451 : 0 : return ret;
452 : : }
453 : : EXPORT_SYMBOL(pci_resize_resource);
454 : :
455 : 84 : int pci_enable_resources(struct pci_dev *dev, int mask)
456 : : {
457 : 84 : u16 cmd, old_cmd;
458 : 84 : int i;
459 : 84 : struct resource *r;
460 : :
461 : 84 : pci_read_config_word(dev, PCI_COMMAND, &cmd);
462 : 84 : old_cmd = cmd;
463 : :
464 [ + + ]: 1008 : for (i = 0; i < PCI_NUM_RESOURCES; i++) {
465 [ + + ]: 924 : if (!(mask & (1 << i)))
466 : 756 : continue;
467 : :
468 : 168 : r = &dev->resource[i];
469 : :
470 [ - + ]: 168 : if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
471 : 0 : continue;
472 [ - + ]: 168 : if ((i == PCI_ROM_RESOURCE) &&
473 [ # # ]: 0 : (!(r->flags & IORESOURCE_ROM_ENABLE)))
474 : 0 : continue;
475 : :
476 [ - + ]: 168 : if (r->flags & IORESOURCE_UNSET) {
477 : 0 : pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
478 : : i, r);
479 : 0 : return -EINVAL;
480 : : }
481 : :
482 [ - + ]: 168 : if (!r->parent) {
483 : 0 : pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
484 : : i, r);
485 : 0 : return -EINVAL;
486 : : }
487 : :
488 [ + + ]: 168 : if (r->flags & IORESOURCE_IO)
489 : 105 : cmd |= PCI_COMMAND_IO;
490 [ + + ]: 168 : if (r->flags & IORESOURCE_MEM)
491 : 63 : cmd |= PCI_COMMAND_MEMORY;
492 : : }
493 : :
494 [ - + ]: 84 : if (cmd != old_cmd) {
495 : 0 : pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
496 : 0 : pci_write_config_word(dev, PCI_COMMAND, cmd);
497 : : }
498 : : return 0;
499 : : }
|