linux/drivers/pci/setup-res.c
<<
>>
Prefs
   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
  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
  34        /* Per SR-IOV spec 3.4.1.11, VF BARs are RO zero */
  35        if (dev->is_virtfn)
  36                return;
  37
  38        /*
  39         * Ignore resources for unimplemented BARs and unused resource slots
  40         * for 64 bit BARs.
  41         */
  42        if (!res->flags)
  43                return;
  44
  45        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        if (res->flags & IORESOURCE_PCI_FIXED)
  54                return;
  55
  56        pcibios_resource_to_bus(dev->bus, &region, res);
  57        new = region.start;
  58
  59        if (res->flags & IORESOURCE_IO) {
  60                mask = (u32)PCI_BASE_ADDRESS_IO_MASK;
  61                new |= res->flags & ~PCI_BASE_ADDRESS_IO_MASK;
  62        } else if (resno == PCI_ROM_RESOURCE) {
  63                mask = PCI_ROM_ADDRESS_MASK;
  64        } else {
  65                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
  66                new |= res->flags & ~PCI_BASE_ADDRESS_MEM_MASK;
  67        }
  68
  69        if (resno < PCI_ROM_RESOURCE) {
  70                reg = PCI_BASE_ADDRESS_0 + 4 * resno;
  71        } 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                if (!(res->flags & IORESOURCE_ROM_ENABLE))
  79                        return;
  80
  81                reg = dev->rom_base_reg;
  82                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        disable = (res->flags & IORESOURCE_MEM_64) && !dev->mmio_always_on;
  92        if (disable) {
  93                pci_read_config_word(dev, PCI_COMMAND, &cmd);
  94                pci_write_config_word(dev, PCI_COMMAND,
  95                                      cmd & ~PCI_COMMAND_MEMORY);
  96        }
  97
  98        pci_write_config_dword(dev, reg, new);
  99        pci_read_config_dword(dev, reg, &check);
 100
 101        if ((new ^ check) & mask) {
 102                pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
 103                        resno, new, check);
 104        }
 105
 106        if (res->flags & IORESOURCE_MEM_64) {
 107                new = region.start >> 16 >> 16;
 108                pci_write_config_dword(dev, reg + 4, new);
 109                pci_read_config_dword(dev, reg + 4, &check);
 110                if (check != new) {
 111                        pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
 112                                resno, new, check);
 113                }
 114        }
 115
 116        if (disable)
 117                pci_write_config_word(dev, PCI_COMMAND, cmd);
 118}
 119
 120void pci_update_resource(struct pci_dev *dev, int resno)
 121{
 122        if (resno <= PCI_ROM_RESOURCE)
 123                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}
 129
 130int pci_claim_resource(struct pci_dev *dev, int resource)
 131{
 132        struct resource *res = &dev->resource[resource];
 133        struct resource *root, *conflict;
 134
 135        if (res->flags & IORESOURCE_UNSET) {
 136                pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
 137                         resource, res);
 138                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        if (res->flags & IORESOURCE_ROM_SHADOW)
 147                return 0;
 148
 149        root = pci_find_parent_resource(dev, res);
 150        if (!root) {
 151                pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
 152                         resource, res);
 153                res->flags |= IORESOURCE_UNSET;
 154                return -EINVAL;
 155        }
 156
 157        conflict = request_resource_conflict(root, res);
 158        if (conflict) {
 159                pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
 160                         resource, res, conflict->name, conflict);
 161                res->flags |= IORESOURCE_UNSET;
 162                return -EBUSY;
 163        }
 164
 165        return 0;
 166}
 167EXPORT_SYMBOL(pci_claim_resource);
 168
 169void pci_disable_bridge_window(struct pci_dev *dev)
 170{
 171        /* MMIO Base/Limit */
 172        pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
 173
 174        /* Prefetchable MMIO Base/Limit */
 175        pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
 176        pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
 177        pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
 178}
 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 */
 189resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx)
 190{
 191        return 0;
 192}
 193
 194static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 195                int resno, resource_size_t size)
 196{
 197        struct resource *root, *conflict;
 198        resource_size_t fw_addr, start, end;
 199
 200        fw_addr = pcibios_retrieve_fw_addr(dev, resno);
 201        if (!fw_addr)
 202                return -ENOMEM;
 203
 204        start = res->start;
 205        end = res->end;
 206        res->start = fw_addr;
 207        res->end = res->start + size - 1;
 208        res->flags &= ~IORESOURCE_UNSET;
 209
 210        root = pci_find_parent_resource(dev, res);
 211        if (!root) {
 212                if (res->flags & IORESOURCE_IO)
 213                        root = &ioport_resource;
 214                else
 215                        root = &iomem_resource;
 216        }
 217
 218        pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
 219                 resno, res);
 220        conflict = request_resource_conflict(root, res);
 221        if (conflict) {
 222                pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
 223                         resno, res, conflict->name, conflict);
 224                res->start = start;
 225                res->end = end;
 226                res->flags |= IORESOURCE_UNSET;
 227                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 */
 237resource_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       return res->start;
 243}
 244
 245static 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        struct resource *res = dev->resource + resno;
 249        resource_size_t min;
 250        int ret;
 251
 252        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        ret = pci_bus_alloc_resource(bus, res, size, align, min,
 262                                     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
 263                                     pcibios_align_resource, dev);
 264        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        if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
 272             (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
 273                ret = pci_bus_alloc_resource(bus, res, size, align, min,
 274                                             IORESOURCE_PREFETCH,
 275                                             pcibios_align_resource, dev);
 276                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        if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
 287                ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
 288                                             pcibios_align_resource, dev);
 289
 290        return ret;
 291}
 292
 293static int _pci_assign_resource(struct pci_dev *dev, int resno,
 294                                resource_size_t size, resource_size_t min_align)
 295{
 296        struct pci_bus *bus;
 297        int ret;
 298
 299        bus = dev->bus;
 300        while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
 301                if (!bus->parent || !bus->self->transparent)
 302                        break;
 303                bus = bus->parent;
 304        }
 305
 306        return ret;
 307}
 308
 309int pci_assign_resource(struct pci_dev *dev, int resno)
 310{
 311        struct resource *res = dev->resource + resno;
 312        resource_size_t align, size;
 313        int ret;
 314
 315        if (res->flags & IORESOURCE_PCI_FIXED)
 316                return 0;
 317
 318        res->flags |= IORESOURCE_UNSET;
 319        align = pci_resource_alignment(dev, res);
 320        if (!align) {
 321                pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
 322                         resno, res);
 323                return -EINVAL;
 324        }
 325
 326        size = resource_size(res);
 327        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        if (ret < 0) {
 335                pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
 336                ret = pci_revert_fw_address(res, dev, resno, size);
 337        }
 338
 339        if (ret < 0) {
 340                pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
 341                return ret;
 342        }
 343
 344        res->flags &= ~IORESOURCE_UNSET;
 345        res->flags &= ~IORESOURCE_STARTALIGN;
 346        pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
 347        if (resno < PCI_BRIDGE_RESOURCES)
 348                pci_update_resource(dev, resno);
 349
 350        return 0;
 351}
 352EXPORT_SYMBOL(pci_assign_resource);
 353
 354int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
 355                        resource_size_t min_align)
 356{
 357        struct resource *res = dev->resource + resno;
 358        unsigned long flags;
 359        resource_size_t new_size;
 360        int ret;
 361
 362        if (res->flags & IORESOURCE_PCI_FIXED)
 363                return 0;
 364
 365        flags = res->flags;
 366        res->flags |= IORESOURCE_UNSET;
 367        if (!res->parent) {
 368                pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
 369                         resno, res);
 370                return -EINVAL;
 371        }
 372
 373        /* already aligned with min_align */
 374        new_size = resource_size(res) + addsize;
 375        ret = _pci_assign_resource(dev, resno, new_size, min_align);
 376        if (ret) {
 377                res->flags = flags;
 378                pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
 379                         resno, res, (unsigned long long) addsize);
 380                return ret;
 381        }
 382
 383        res->flags &= ~IORESOURCE_UNSET;
 384        res->flags &= ~IORESOURCE_STARTALIGN;
 385        pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
 386                 resno, res, (unsigned long long) addsize);
 387        if (resno < PCI_BRIDGE_RESOURCES)
 388                pci_update_resource(dev, resno);
 389
 390        return 0;
 391}
 392
 393void pci_release_resource(struct pci_dev *dev, int resno)
 394{
 395        struct resource *res = dev->resource + resno;
 396
 397        pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
 398
 399        if (!res->parent)
 400                return;
 401
 402        release_resource(res);
 403        res->end = resource_size(res) - 1;
 404        res->start = 0;
 405        res->flags |= IORESOURCE_UNSET;
 406}
 407EXPORT_SYMBOL(pci_release_resource);
 408
 409int pci_resize_resource(struct pci_dev *dev, int resno, int size)
 410{
 411        struct resource *res = dev->resource + resno;
 412        int old, ret;
 413        u32 sizes;
 414        u16 cmd;
 415
 416        /* Make sure the resource isn't assigned before resizing it. */
 417        if (!(res->flags & IORESOURCE_UNSET))
 418                return -EBUSY;
 419
 420        pci_read_config_word(dev, PCI_COMMAND, &cmd);
 421        if (cmd & PCI_COMMAND_MEMORY)
 422                return -EBUSY;
 423
 424        sizes = pci_rebar_get_possible_sizes(dev, resno);
 425        if (!sizes)
 426                return -ENOTSUPP;
 427
 428        if (!(sizes & BIT(size)))
 429                return -EINVAL;
 430
 431        old = pci_rebar_get_current_size(dev, resno);
 432        if (old < 0)
 433                return old;
 434
 435        ret = pci_rebar_set_size(dev, resno, size);
 436        if (ret)
 437                return ret;
 438
 439        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        ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
 443        if (ret)
 444                goto error_resize;
 445
 446        return 0;
 447
 448error_resize:
 449        pci_rebar_set_size(dev, resno, old);
 450        res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
 451        return ret;
 452}
 453EXPORT_SYMBOL(pci_resize_resource);
 454
 455int pci_enable_resources(struct pci_dev *dev, int mask)
 456{
 457        u16 cmd, old_cmd;
 458        int i;
 459        struct resource *r;
 460
 461        pci_read_config_word(dev, PCI_COMMAND, &cmd);
 462        old_cmd = cmd;
 463
 464        for (i = 0; i < PCI_NUM_RESOURCES; i++) {
 465                if (!(mask & (1 << i)))
 466                        continue;
 467
 468                r = &dev->resource[i];
 469
 470                if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
 471                        continue;
 472                if ((i == PCI_ROM_RESOURCE) &&
 473                                (!(r->flags & IORESOURCE_ROM_ENABLE)))
 474                        continue;
 475
 476                if (r->flags & IORESOURCE_UNSET) {
 477                        pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
 478                                i, r);
 479                        return -EINVAL;
 480                }
 481
 482                if (!r->parent) {
 483                        pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
 484                                i, r);
 485                        return -EINVAL;
 486                }
 487
 488                if (r->flags & IORESOURCE_IO)
 489                        cmd |= PCI_COMMAND_IO;
 490                if (r->flags & IORESOURCE_MEM)
 491                        cmd |= PCI_COMMAND_MEMORY;
 492        }
 493
 494        if (cmd != old_cmd) {
 495                pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
 496                pci_write_config_word(dev, PCI_COMMAND, cmd);
 497        }
 498        return 0;
 499}
 500