brintos

brintos / linux-shallow public Read only

0
0
Text · 13.7 KiB · c6d933d Raw
529 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Support routines for initializing a PCI subsystem4 *5 * Extruded from code written by6 *      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 sorting14 */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 25static void pci_std_update_resource(struct pci_dev *dev, int resno)26{27	struct pci_bus_region region;28	bool disable;29	u16 cmd;30	u32 new, check, mask;31	int reg;32	struct resource *res = dev->resource + resno;33	const char *res_name = pci_resource_name(dev, resno);34 35	/* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */36	if (dev->is_virtfn)37		return;38 39	/*40	 * Ignore resources for unimplemented BARs and unused resource slots41	 * for 64 bit BARs.42	 */43	if (!res->flags)44		return;45 46	if (res->flags & IORESOURCE_UNSET)47		return;48 49	/*50	 * Ignore non-moveable resources.  This might be legacy resources for51	 * which no functional BAR register exists or another important52	 * system resource we shouldn't move around.53	 */54	if (res->flags & IORESOURCE_PCI_FIXED)55		return;56 57	pcibios_resource_to_bus(dev->bus, &region, res);58	new = region.start;59 60	if (res->flags & IORESOURCE_IO) {61		mask = (u32)PCI_BASE_ADDRESS_IO_MASK;62		new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;63	} else if (resno == PCI_ROM_RESOURCE) {64		mask = PCI_ROM_ADDRESS_MASK;65	} else {66		mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;67		new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;68	}69 70	if (resno < PCI_ROM_RESOURCE) {71		reg = PCI_BASE_ADDRESS_0 + 4 * resno;72	} else if (resno == PCI_ROM_RESOURCE) {73 74		/*75		 * Apparently some Matrox devices have ROM BARs that read76		 * as zero when disabled, so don't update ROM BARs unless77		 * they're enabled.  See78		 * https://lore.kernel.org/r/43147B3D.1030309@vc.cvut.cz/79		 * But we must update ROM BAR for buggy devices where even a80		 * disabled ROM can conflict with other BARs.81		 */82		if (!(res->flags & IORESOURCE_ROM_ENABLE) &&83		    !dev->rom_bar_overlap)84			return;85 86		reg = dev->rom_base_reg;87		if (res->flags & IORESOURCE_ROM_ENABLE)88			new |= PCI_ROM_ADDRESS_ENABLE;89	} else90		return;91 92	/*93	 * We can't update a 64-bit BAR atomically, so when possible,94	 * disable decoding so that a half-updated BAR won't conflict95	 * with another device.96	 */97	disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;98	if (disable) {99		pci_read_config_word(dev, PCI_COMMAND, &cmd);100		pci_write_config_word(dev, PCI_COMMAND,101				      cmd & ~PCI_COMMAND_MEMORY);102	}103 104	pci_write_config_dword(dev, reg, new);105	pci_read_config_dword(dev, reg, &check);106 107	if ((new ^ check) & mask) {108		pci_err(dev, "%s: error updating (%#010x != %#010x)\n",109			res_name, new, check);110	}111 112	if (res->flags & IORESOURCE_MEM_64) {113		new = region.start >> 16 >> 16;114		pci_write_config_dword(dev, reg + 4, new);115		pci_read_config_dword(dev, reg + 4, &check);116		if (check != new) {117			pci_err(dev, "%s: error updating (high %#010x != %#010x)\n",118				res_name, new, check);119		}120	}121 122	if (disable)123		pci_write_config_word(dev, PCI_COMMAND, cmd);124}125 126void pci_update_resource(struct pci_dev *dev, int resno)127{128	if (resno <= PCI_ROM_RESOURCE)129		pci_std_update_resource(dev, resno);130#ifdef CONFIG_PCI_IOV131	else if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)132		pci_iov_update_resource(dev, resno);133#endif134}135 136int pci_claim_resource(struct pci_dev *dev, int resource)137{138	struct resource *res = &dev->resource[resource];139	const char *res_name = pci_resource_name(dev, resource);140	struct resource *root, *conflict;141 142	if (res->flags & IORESOURCE_UNSET) {143		pci_info(dev, "%s %pR: can't claim; no address assigned\n",144			 res_name, res);145		return -EINVAL;146	}147 148	/*149	 * If we have a shadow copy in RAM, the PCI device doesn't respond150	 * to the shadow range, so we don't need to claim it, and upstream151	 * bridges don't need to route the range to the device.152	 */153	if (res->flags & IORESOURCE_ROM_SHADOW)154		return 0;155 156	root = pci_find_parent_resource(dev, res);157	if (!root) {158		pci_info(dev, "%s %pR: can't claim; no compatible bridge window\n",159			 res_name, res);160		res->flags |= IORESOURCE_UNSET;161		return -EINVAL;162	}163 164	conflict = request_resource_conflict(root, res);165	if (conflict) {166		pci_info(dev, "%s %pR: can't claim; address conflict with %s %pR\n",167			 res_name, res, conflict->name, conflict);168		res->flags |= IORESOURCE_UNSET;169		return -EBUSY;170	}171 172	return 0;173}174EXPORT_SYMBOL(pci_claim_resource);175 176void pci_disable_bridge_window(struct pci_dev *dev)177{178	/* MMIO Base/Limit */179	pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);180 181	/* Prefetchable MMIO Base/Limit */182	pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);183	pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);184	pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);185}186 187/*188 * Generic function that returns a value indicating that the device's189 * original BIOS BAR address was not saved and so is not available for190 * reinstatement.191 *192 * Can be over-ridden by architecture specific code that implements193 * reinstatement functionality rather than leaving it disabled when194 * normal allocation attempts fail.195 */196resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)197{198	return 0;199}200 201static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,202		int resno, resource_size_t size)203{204	struct resource *root, *conflict;205	resource_size_t fw_addr, start, end;206	const char *res_name = pci_resource_name(dev, resno);207 208	fw_addr = pcibios_retrieve_fw_addr(dev, resno);209	if (!fw_addr)210		return -ENOMEM;211 212	start = res->start;213	end = res->end;214	res->start = fw_addr;215	res->end = res->start + size - 1;216	res->flags &= ~IORESOURCE_UNSET;217 218	root = pci_find_parent_resource(dev, res);219	if (!root) {220		/*221		 * If dev is behind a bridge, accesses will only reach it222		 * if res is inside the relevant bridge window.223		 */224		if (pci_upstream_bridge(dev))225			return -ENXIO;226 227		/*228		 * On the root bus, assume the host bridge will forward229		 * everything.230		 */231		if (res->flags & IORESOURCE_IO)232			root = &ioport_resource;233		else234			root = &iomem_resource;235	}236 237	pci_info(dev, "%s: trying firmware assignment %pR\n", res_name, res);238	conflict = request_resource_conflict(root, res);239	if (conflict) {240		pci_info(dev, "%s %pR: conflicts with %s %pR\n", res_name, res,241			 conflict->name, conflict);242		res->start = start;243		res->end = end;244		res->flags |= IORESOURCE_UNSET;245		return -EBUSY;246	}247	return 0;248}249 250/*251 * We don't have to worry about legacy ISA devices, so nothing to do here.252 * This is marked as __weak because multiple architectures define it; it should253 * eventually go away.254 */255resource_size_t __weak pcibios_align_resource(void *data,256					      const struct resource *res,257					      resource_size_t size,258					      resource_size_t align)259{260       return res->start;261}262 263static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,264		int resno, resource_size_t size, resource_size_t align)265{266	struct resource *res = dev->resource + resno;267	resource_size_t min;268	int ret;269 270	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;271 272	/*273	 * First, try exact prefetching match.  Even if a 64-bit274	 * prefetchable bridge window is below 4GB, we can't put a 32-bit275	 * prefetchable resource in it because pbus_size_mem() assumes a276	 * 64-bit window will contain no 32-bit resources.  If we assign277	 * things differently than they were sized, not everything will fit.278	 */279	ret = pci_bus_alloc_resource(bus, res, size, align, min,280				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,281				     pcibios_align_resource, dev);282	if (ret == 0)283		return 0;284 285	/*286	 * If the prefetchable window is only 32 bits wide, we can put287	 * 64-bit prefetchable resources in it.288	 */289	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==290	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {291		ret = pci_bus_alloc_resource(bus, res, size, align, min,292					     IORESOURCE_PREFETCH,293					     pcibios_align_resource, dev);294		if (ret == 0)295			return 0;296	}297 298	/*299	 * If we didn't find a better match, we can put any memory resource300	 * in a non-prefetchable window.  If this resource is 32 bits and301	 * non-prefetchable, the first call already tried the only possibility302	 * so we don't need to try again.303	 */304	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))305		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,306					     pcibios_align_resource, dev);307 308	return ret;309}310 311static int _pci_assign_resource(struct pci_dev *dev, int resno,312				resource_size_t size, resource_size_t min_align)313{314	struct pci_bus *bus;315	int ret;316 317	bus = dev->bus;318	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {319		if (!bus->parent || !bus->self->transparent)320			break;321		bus = bus->parent;322	}323 324	return ret;325}326 327int pci_assign_resource(struct pci_dev *dev, int resno)328{329	struct resource *res = dev->resource + resno;330	const char *res_name = pci_resource_name(dev, resno);331	resource_size_t align, size;332	int ret;333 334	if (res->flags & IORESOURCE_PCI_FIXED)335		return 0;336 337	res->flags |= IORESOURCE_UNSET;338	align = pci_resource_alignment(dev, res);339	if (!align) {340		pci_info(dev, "%s %pR: can't assign; bogus alignment\n",341			 res_name, res);342		return -EINVAL;343	}344 345	size = resource_size(res);346	ret = _pci_assign_resource(dev, resno, size, align);347 348	/*349	 * If we failed to assign anything, let's try the address350	 * where firmware left it.  That at least has a chance of351	 * working, which is better than just leaving it disabled.352	 */353	if (ret < 0) {354		pci_info(dev, "%s %pR: can't assign; no space\n", res_name, res);355		ret = pci_revert_fw_address(res, dev, resno, size);356	}357 358	if (ret < 0) {359		pci_info(dev, "%s %pR: failed to assign\n", res_name, res);360		return ret;361	}362 363	res->flags &= ~IORESOURCE_UNSET;364	res->flags &= ~IORESOURCE_STARTALIGN;365	pci_info(dev, "%s %pR: assigned\n", res_name, res);366	if (resno < PCI_BRIDGE_RESOURCES)367		pci_update_resource(dev, resno);368 369	return 0;370}371EXPORT_SYMBOL(pci_assign_resource);372 373int pci_reassign_resource(struct pci_dev *dev, int resno,374			  resource_size_t addsize, resource_size_t min_align)375{376	struct resource *res = dev->resource + resno;377	const char *res_name = pci_resource_name(dev, resno);378	unsigned long flags;379	resource_size_t new_size;380	int ret;381 382	if (res->flags & IORESOURCE_PCI_FIXED)383		return 0;384 385	flags = res->flags;386	res->flags |= IORESOURCE_UNSET;387	if (!res->parent) {388		pci_info(dev, "%s %pR: can't reassign; unassigned resource\n",389			 res_name, res);390		return -EINVAL;391	}392 393	/* already aligned with min_align */394	new_size = resource_size(res) + addsize;395	ret = _pci_assign_resource(dev, resno, new_size, min_align);396	if (ret) {397		res->flags = flags;398		pci_info(dev, "%s %pR: failed to expand by %#llx\n",399			 res_name, res, (unsigned long long) addsize);400		return ret;401	}402 403	res->flags &= ~IORESOURCE_UNSET;404	res->flags &= ~IORESOURCE_STARTALIGN;405	pci_info(dev, "%s %pR: reassigned; expanded by %#llx\n",406		 res_name, res, (unsigned long long) addsize);407	if (resno < PCI_BRIDGE_RESOURCES)408		pci_update_resource(dev, resno);409 410	return 0;411}412 413void pci_release_resource(struct pci_dev *dev, int resno)414{415	struct resource *res = dev->resource + resno;416	const char *res_name = pci_resource_name(dev, resno);417 418	pci_info(dev, "%s %pR: releasing\n", res_name, res);419 420	if (!res->parent)421		return;422 423	release_resource(res);424	res->end = resource_size(res) - 1;425	res->start = 0;426	res->flags |= IORESOURCE_UNSET;427}428EXPORT_SYMBOL(pci_release_resource);429 430int pci_resize_resource(struct pci_dev *dev, int resno, int size)431{432	struct resource *res = dev->resource + resno;433	struct pci_host_bridge *host;434	int old, ret;435	u32 sizes;436	u16 cmd;437 438	/* Check if we must preserve the firmware's resource assignment */439	host = pci_find_host_bridge(dev->bus);440	if (host->preserve_config)441		return -ENOTSUPP;442 443	/* Make sure the resource isn't assigned before resizing it. */444	if (!(res->flags & IORESOURCE_UNSET))445		return -EBUSY;446 447	pci_read_config_word(dev, PCI_COMMAND, &cmd);448	if (cmd & PCI_COMMAND_MEMORY)449		return -EBUSY;450 451	sizes = pci_rebar_get_possible_sizes(dev, resno);452	if (!sizes)453		return -ENOTSUPP;454 455	if (!(sizes & BIT(size)))456		return -EINVAL;457 458	old = pci_rebar_get_current_size(dev, resno);459	if (old < 0)460		return old;461 462	ret = pci_rebar_set_size(dev, resno, size);463	if (ret)464		return ret;465 466	res->end = res->start + pci_rebar_size_to_bytes(size) - 1;467 468	/* Check if the new config works by trying to assign everything. */469	if (dev->bus->self) {470		ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);471		if (ret)472			goto error_resize;473	}474	return 0;475 476error_resize:477	pci_rebar_set_size(dev, resno, old);478	res->end = res->start + pci_rebar_size_to_bytes(old) - 1;479	return ret;480}481EXPORT_SYMBOL(pci_resize_resource);482 483int pci_enable_resources(struct pci_dev *dev, int mask)484{485	u16 cmd, old_cmd;486	int i;487	struct resource *r;488	const char *r_name;489 490	pci_read_config_word(dev, PCI_COMMAND, &cmd);491	old_cmd = cmd;492 493	pci_dev_for_each_resource(dev, r, i) {494		if (!(mask & (1 << i)))495			continue;496 497		r_name = pci_resource_name(dev, i);498 499		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))500			continue;501		if ((i == PCI_ROM_RESOURCE) &&502				(!(r->flags & IORESOURCE_ROM_ENABLE)))503			continue;504 505		if (r->flags & IORESOURCE_UNSET) {506			pci_err(dev, "%s %pR: not assigned; can't enable device\n",507				r_name, r);508			return -EINVAL;509		}510 511		if (!r->parent) {512			pci_err(dev, "%s %pR: not claimed; can't enable device\n",513				r_name, r);514			return -EINVAL;515		}516 517		if (r->flags & IORESOURCE_IO)518			cmd |= PCI_COMMAND_IO;519		if (r->flags & IORESOURCE_MEM)520			cmd |= PCI_COMMAND_MEMORY;521	}522 523	if (cmd != old_cmd) {524		pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);525		pci_write_config_word(dev, PCI_COMMAND, cmd);526	}527	return 0;528}529