]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
pci: Map bars with offset and length
authorAndrew Scull <ascull@google.com>
Thu, 21 Apr 2022 16:11:10 +0000 (16:11 +0000)
committerTom Rini <trini@konsulko.com>
Tue, 3 May 2022 19:50:46 +0000 (15:50 -0400)
Evolve dm_pci_map_bar() to include an offset and length parameter. These
allow a portion of the memory to be mapped and range checks to be
applied.

Passing both the offset and length as zero results in the previous
behaviour and this is used to migrate the previous callers.

Signed-off-by: Andrew Scull <ascull@google.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
33 files changed:
arch/x86/cpu/baytrail/cpu.c
drivers/ata/ahci.c
drivers/ata/sata_sil.c
drivers/gpio/octeon_gpio.c
drivers/i2c/designware_i2c_pci.c
drivers/i2c/intel_i2c.c
drivers/i2c/octeon_i2c.c
drivers/mmc/octeontx_hsmmc.c
drivers/mmc/pci_mmc.c
drivers/mtd/nand/raw/octeontx_bch.c
drivers/mtd/nand/raw/octeontx_nand.c
drivers/net/bnxt/bnxt.c
drivers/net/e1000.c
drivers/net/fsl_enetc.c
drivers/net/fsl_enetc_mdio.c
drivers/net/mscc_eswitch/felix_switch.c
drivers/net/octeontx/bgx.c
drivers/net/octeontx/nic_main.c
drivers/net/octeontx/nicvf_main.c
drivers/net/octeontx/smi.c
drivers/net/octeontx2/cgx.c
drivers/net/octeontx2/rvu_af.c
drivers/net/octeontx2/rvu_pf.c
drivers/net/pch_gbe.c
drivers/nvme/nvme_pci.c
drivers/pci/pci-uclass.c
drivers/spi/octeon_spi.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/xhci-pci.c
drivers/virtio/virtio_pci_legacy.c
include/pci.h
test/dm/pci.c

index 68bf40ba8e818d7240bece418c1136c7fe570301..9b6ac5dd592ee118885a6fb2d0a44125a98cdd41 100644 (file)
@@ -56,7 +56,7 @@ static int baytrail_uart_init(void *ctx, struct event *event)
        for (i = 0; i < 2; i++) {
                ret = dm_pci_bus_find_bdf(PCI_BDF(0, 0x1e, 3 + i), &dev);
                if (!ret) {
-                       base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+                       base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                              PCI_REGION_MEM);
                        hsuart_clock_set(base);
                }
index 2062197afcd3bd41b40cdd6fa072c7d907464230..3925807d55ed1cc6f2b016cb069304d6f00259b9 100644 (file)
@@ -416,8 +416,8 @@ static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev)
        uc_priv->udma_mask = 0x7f;      /*Fixme,assume to support UDMA6 */
 
 #if !defined(CONFIG_DM_SCSI)
-       uc_priv->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5,
-                                             PCI_REGION_MEM);
+       uc_priv->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5, 0, 0,
+                                           PCI_REGION_MEM);
 
        /* Take from kernel:
         * JMicron-specific fixup:
@@ -1148,7 +1148,7 @@ int ahci_probe_scsi_pci(struct udevice *ahci_dev)
        ulong base;
        u16 vendor, device;
 
-       base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5,
+       base = (ulong)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_5, 0, 0,
                                     PCI_REGION_MEM);
 
        /*
@@ -1163,7 +1163,7 @@ int ahci_probe_scsi_pci(struct udevice *ahci_dev)
 
        if (vendor == PCI_VENDOR_ID_CAVIUM &&
            device == PCI_DEVICE_ID_CAVIUM_SATA)
-               base = (uintptr_t)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_0,
+               base = (uintptr_t)dm_pci_map_bar(ahci_dev, PCI_BASE_ADDRESS_0, 0, 0,
                                                 PCI_REGION_MEM);
        return ahci_probe_scsi(ahci_dev, base);
 }
index b213ebac2fb987bc0d5ac13ac959cf0136f7a820..8806e3fbbbc428912dc1757c88c44e37e9888e6e 100644 (file)
@@ -699,9 +699,9 @@ static int sil_pci_probe(struct udevice *dev)
 
        /* Read out all BARs */
        sata_info.iobase[0] = (ulong)dm_pci_map_bar(dev,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+                       PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        sata_info.iobase[1] = (ulong)dm_pci_map_bar(dev,
-                       PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
+                       PCI_BASE_ADDRESS_2, 0, 0, PCI_REGION_MEM);
 
        /* mask out the unused bits */
        sata_info.iobase[0] &= 0xffffff80;
index 42eae79d8c4227098150e0b4ed61433fbe18a5e9..e6a8e1a5212c569f341cc9005328bef9ba342fdf 100644 (file)
@@ -183,7 +183,7 @@ static int octeon_gpio_probe(struct udevice *dev)
        priv->data = (const struct octeon_gpio_data *)dev_get_driver_data(dev);
 
        if (priv->data->probe == PROBE_PCI) {
-               priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+               priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                            PCI_REGION_MEM);
                uc_priv->gpio_count = readq(priv->base +
                                            priv->data->reg_offs + GPIO_CONST) &
index 9e387737b6ec9a7355f42f6d655b2d8e710671d7..51f1357d10e961b140862037fffe0f92d7717e85 100644 (file)
@@ -59,7 +59,7 @@ static int designware_i2c_pci_of_to_plat(struct udevice *dev)
                priv->regs = (struct i2c_regs *)dm_pci_read_bar32(dev, 0);
        } else {
                priv->regs = (struct i2c_regs *)
-                       dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+                       dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        }
        if (!priv->regs)
                return -EINVAL;
index 52f7a528efe8f6300bfbe8b7c2e934f044538575..7b5b62e3ebb78ebd5130b30d0a8f858f72e8224b 100644 (file)
@@ -251,7 +251,7 @@ static int intel_i2c_probe(struct udevice *dev)
        ulong base;
 
        /* Save base address from PCI BAR */
-       priv->base = (ulong)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4,
+       priv->base = (ulong)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0, 0,
                                           PCI_REGION_IO);
        base = priv->base;
 
index 50199ff46ef9f43d7f6c2964f5c852e7ec293380..74fd5c3d2e8f264f18ce34d8675089a28da207d2 100644 (file)
@@ -792,7 +792,7 @@ static int octeon_i2c_probe(struct udevice *dev)
 
                debug("TWSI PCI device: %x\n", bdf);
 
-               twsi->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+               twsi->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                            PCI_REGION_MEM);
        } else {
                twsi->base = dev_remap_addr(dev);
index f0519f0cf890afa71c1e3eb7624cbd39382b00ef..0bf38945a1d5250d085836353bf20097b13caf87 100644 (file)
@@ -3822,7 +3822,7 @@ static int octeontx_mmc_host_probe(struct udevice *dev)
 
        /* Octeon TX & TX2 use PCI based probing */
        if (device_is_compatible(dev, "cavium,thunder-8890-mmc")) {
-               host->base_addr = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+               host->base_addr = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                                 PCI_REGION_MEM);
                if (!host->base_addr) {
                        pr_err("%s: Error: MMC base address not found\n",
index b9ab064b60e01bdde4657f046561d9eeeb5fffe1..1bc2fbcfdfc477b863de9690a9de2b3f5fb0cdd7 100644 (file)
@@ -50,7 +50,7 @@ static int pci_mmc_probe(struct udevice *dev)
        desc = mmc_get_blk_desc(&plat->mmc);
        desc->removable = !(plat->cfg.host_caps & MMC_CAP_NONREMOVABLE);
 
-       host->ioaddr = (void *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       host->ioaddr = (void *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                              PCI_REGION_MEM);
        host->name = dev->name;
        host->cd_gpio = priv->cd_gpio;
index 24ffa5105f3da0ec1a0875fea7ef95e60ba4b176..c1cc5fa187296d9b08756b560b4a77512aed0f22 100644 (file)
@@ -176,7 +176,7 @@ static int octeontx_pci_bchpf_probe(struct udevice *dev)
        if (!bch)
                return -ENOMEM;
 
-       bch->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       bch->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        bch->dev = dev;
 
        debug("%s: base address: %p\n", __func__, bch->reg_base);
@@ -361,7 +361,7 @@ static int octeontx_pci_bchvf_probe(struct udevice *dev)
        vf->dev = dev;
 
        /* Map PF's configuration registers */
-       vf->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       vf->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        debug("%s: reg base: %p\n", __func__, vf->reg_base);
 
        err = octeontx_cmd_queue_initialize(dev, QID_BCH, QDEPTH - 1, 0,
index ff363a56b51d39ab3b1ab41b830f5700f1f193cc..3e84bb2fc062e27e6d8ba09b8a500dfb71037168 100644 (file)
@@ -2098,7 +2098,7 @@ static int octeontx_pci_nand_probe(struct udevice *dev)
        tn->dev = dev;
        INIT_LIST_HEAD(&tn->chips);
 
-       tn->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       tn->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        if (!tn->base) {
                ret = -EINVAL;
                goto release;
index 9844e96072e77b7f850e02ad91e46e9464f8e8ba..a24f965ec158d65e5b43f336b92ad4efcb00ae08 100644 (file)
@@ -28,9 +28,9 @@ static void bnxt_bring_pci(struct bnxt *bp)
        dm_pci_read_config16(bp->pdev, PCI_SUBSYSTEM_ID, &bp->subsystem_device);
        dm_pci_read_config16(bp->pdev, PCI_COMMAND, &bp->cmd_reg);
        dm_pci_read_config8(bp->pdev, PCI_INTERRUPT_LINE, &bp->irq);
-       bp->bar0 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-       bp->bar1 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
-       bp->bar2 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_4, PCI_REGION_MEM);
+       bp->bar0 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
+       bp->bar1 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_2, 0, 0, PCI_REGION_MEM);
+       bp->bar2 = dm_pci_map_bar(bp->pdev, PCI_BASE_ADDRESS_4, 0, 0, PCI_REGION_MEM);
        cmd_reg = bp->cmd_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
        cmd_reg |= PCI_COMMAND_INTX_DISABLE; /* disable intr */
        dm_pci_write_config16(bp->pdev, PCI_COMMAND, cmd_reg);
index 4e34248ff6f0cbaed8733e7a43e62580b3bf0483..f01c464e4804207380e2327e0e2f613865f569a7 100644 (file)
@@ -5549,7 +5549,7 @@ static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno,
        hw->eeprom_semaphore_present = true;
 #endif
 #ifdef CONFIG_DM_ETH
-       hw->hw_addr = dm_pci_map_bar(devno,     PCI_BASE_ADDRESS_0,
+       hw->hw_addr = dm_pci_map_bar(devno,     PCI_BASE_ADDRESS_0, 0, 0,
                                                PCI_REGION_MEM);
 #else
        hw->hw_addr = pci_map_bar(devno,        PCI_BASE_ADDRESS_0,
index 1724f948bcd564540ffb83a570af2b48e16c6270..ec849cc34d89847092154be41236e5caeb048b35 100644 (file)
@@ -339,7 +339,7 @@ static int enetc_probe(struct udevice *dev)
        }
 
        /* initialize register */
-       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
+       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, 0);
        if (!priv->regs_base) {
                enetc_dbg(dev, "failed to map BAR0\n");
                return -EINVAL;
index 3eb6ac9fc8f036c40dcad7a70d36873017a63b0e..f025c2255c38261d0259e506a1fda5d3cf41d028 100644 (file)
@@ -125,7 +125,7 @@ static int enetc_mdio_probe(struct udevice *dev)
 {
        struct enetc_mdio_priv *priv = dev_get_priv(dev);
 
-       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
+       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, 0);
        if (!priv->regs_base) {
                enetc_dbg(dev, "failed to map BAR0\n");
                return -EINVAL;
index 60b2e8f32d4bb79f40ed33343824ce723a1b28cf..0badb238282e4023f7531d7a62fc1483254c789d 100644 (file)
@@ -292,13 +292,13 @@ static int felix_probe(struct udevice *dev)
                return -ENODEV;
        }
 
-       priv->imdio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
+       priv->imdio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, 0);
        if (!priv->imdio_base) {
                dev_err(dev, "failed to map BAR0\n");
                return -EINVAL;
        }
 
-       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0);
+       priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, 0, 0, 0);
        if (!priv->regs_base) {
                dev_err(dev, "failed to map BAR4\n");
                return -EINVAL;
index a5c0c9fe2b3b8726cf65d819d1abf28b137c3bf5..cc8ef099c226cac955bdd6826135e0f04e90a390 100644 (file)
@@ -1458,7 +1458,7 @@ int octeontx_bgx_probe(struct udevice *dev)
        int bgx_idx, node;
        int inc = 1;
 
-       bgx->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       bgx->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                       PCI_REGION_MEM);
        if (!bgx->reg_base) {
                debug("No PCI region found\n");
index 0f36f2586e6356037d30aa7310b0932cdefc723d..4754c042f10f8f1ace05fea28fa070f93618e0de 100644 (file)
@@ -713,7 +713,7 @@ int nic_initialize(struct udevice *dev)
                return -ENOMEM;
 
        /* MAP PF's configuration registers */
-       nic->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       nic->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                       PCI_REGION_MEM);
        if (!nic->reg_base) {
                printf("Cannot map config register space, aborting\n");
index c30ba49c27c338b6fbd4d128e905e9d116028f80..097df6df1eb2cbe3cfd9c50dcdb9f0a0e4e0f5f0 100644 (file)
@@ -509,7 +509,7 @@ int nicvf_initialize(struct udevice *dev)
        /* Enable TSO support */
        nicvf->hw_tso = true;
 
-       nicvf->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       nicvf->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                         PCI_REGION_MEM);
 
        debug("nicvf->reg_base: %p\n", nicvf->reg_base);
index d70fa820c7b0fdb36632d7bfabfcba8ae20e40a0..2d521bd3ca7ef02bf3a6ff230a006a55f8a4c32a 100644 (file)
@@ -322,7 +322,7 @@ int octeontx_smi_probe(struct udevice *dev)
        u64 baseaddr;
 
        debug("SMI PCI device: %x\n", bdf);
-       if (!dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM)) {
+       if (!dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM)) {
                printf("Failed to map PCI region for bdf %x\n", bdf);
                return -1;
        }
index d139029f4e5a99cc81e4dc4e89e42cfdcf453fe3..eed31a9579339cf9fef1d2e127c9c1a22f154f75 100644 (file)
@@ -253,7 +253,7 @@ int cgx_probe(struct udevice *dev)
        struct cgx *cgx = dev_get_priv(dev);
        int err;
 
-       cgx->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       cgx->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                       PCI_REGION_MEM);
        cgx->dev = dev;
        cgx->cgx_id = ((u64)(cgx->reg_base) >> 24) & 0x7;
index d2f965486116b0711643a45475971108146f08b8..47c1502ef8b24b46d84644021a580f65f00760c2 100644 (file)
@@ -127,7 +127,7 @@ int rvu_af_probe(struct udevice *dev)
 {
        struct rvu_af *af_ptr = dev_get_priv(dev);
 
-       af_ptr->af_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+       af_ptr->af_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                         PCI_REGION_MEM);
        debug("%s RVU AF BAR %p\n", __func__, af_ptr->af_base);
        af_ptr->dev = dev;
index 4b00178989cf4fb9c8aea8014958754ac9201804..024e17e748345d6b52e749ef17ec7345612bca3f 100644 (file)
@@ -58,7 +58,7 @@ int rvu_pf_probe(struct udevice *dev)
 
        debug("%s: name: %s\n", __func__, dev->name);
 
-       rvu->pf_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_2, PCI_REGION_MEM);
+       rvu->pf_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_2, 0, 0, PCI_REGION_MEM);
        rvu->pfid = dev_seq(dev) + 1; // RVU PF's start from 1;
        rvu->dev = dev;
        if (!rvu_af_dev) {
index f1895246b93ab28d12c9830674854dabc1d6ec93..c795c8f15326ed47d596936d5b2e8d0116063026 100644 (file)
@@ -449,7 +449,7 @@ static int pch_gbe_probe(struct udevice *dev)
 
        priv->dev = dev;
 
-       iobase = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, PCI_REGION_MEM);
+       iobase = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_1, 0, 0, PCI_REGION_MEM);
 
        plat->iobase = (ulong)iobase;
        priv->mac_regs = (struct pch_gbe_regs *)iobase;
index 5f60fb884fb634db4a77d7a7c37f9bd7f212b87c..3499a7b6e7233b28012ae30644d79401db5e0f5f 100644 (file)
@@ -28,8 +28,8 @@ static int nvme_probe(struct udevice *udev)
        sprintf(ndev->vendor, "0x%.4x", pplat->vendor);
 
        ndev->instance = trailing_strtol(udev->name);
-       ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0,
-                       PCI_REGION_MEM);
+       ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0,
+                                  PCI_REGION_MEM);
        return nvme_init(udev);
 }
 
index 997ca0d5e4d28d1d6170f7b2eaf46d1c8f96066f..9fe07cfd34f71ad7f00d145bf75a56c464c187f1 100644 (file)
@@ -1561,7 +1561,8 @@ static phys_addr_t dm_pci_map_ea_virt(struct udevice *dev, int ea_off,
        return addr;
 }
 
-static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int ea_off,
+static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, size_t offset,
+                              size_t len, int ea_off,
                               struct pci_child_plat *pdata)
 {
        int ea_cnt, i, entry_size;
@@ -1604,14 +1605,18 @@ static void *dm_pci_map_ea_bar(struct udevice *dev, int bar, int ea_off,
                if (IS_ENABLED(CONFIG_PCI_SRIOV))
                        addr += dm_pci_map_ea_virt(dev, ea_off, pdata);
 
+               if (~((phys_addr_t)0) - addr < offset)
+                       return NULL;
+
                /* size ignored for now */
-               return map_physmem(addr, 0, MAP_NOCACHE);
+               return map_physmem(addr + offset, len, MAP_NOCACHE);
        }
 
        return 0;
 }
 
-void *dm_pci_map_bar(struct udevice *dev, int bar, unsigned long flags)
+void *dm_pci_map_bar(struct udevice *dev, int bar, size_t offset, size_t len,
+                    unsigned long flags)
 {
        struct pci_child_plat *pdata = dev_get_parent_plat(dev);
        struct udevice *udev = dev;
@@ -1636,19 +1641,23 @@ void *dm_pci_map_bar(struct udevice *dev, int bar, unsigned long flags)
         */
        ea_off = dm_pci_find_capability(udev, PCI_CAP_ID_EA);
        if (ea_off)
-               return dm_pci_map_ea_bar(udev, bar, ea_off, pdata);
+               return dm_pci_map_ea_bar(udev, bar, offset, len, ea_off, pdata);
 
        /* read BAR address */
        dm_pci_read_config32(udev, bar, &bar_response);
        pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
 
+       if (~((pci_addr_t)0) - pci_bus_addr < offset)
+               return NULL;
+
        /*
-        * Pass "0" as the length argument to pci_bus_to_virt.  The arg
-        * isn't actually used on any platform because U-Boot assumes a static
-        * linear mapping.  In the future, this could read the BAR size
-        * and pass that as the size if needed.
+        * Forward the length argument to dm_pci_bus_to_virt. The length will
+        * be used to check that the entire address range has been declared as
+        * a PCI range, but a better check would be to probe for the size of
+        * the bar and prevent overflow more locally.
         */
-       return dm_pci_bus_to_virt(udev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+       return dm_pci_bus_to_virt(udev, pci_bus_addr + offset, flags, len,
+                                 MAP_NOCACHE);
 }
 
 static int _dm_pci_find_next_capability(struct udevice *dev, u8 pos, int cap)
index fcabc112d20943231e34a8de5575c8c70284ea7d..2f8a8a86498dfac7fd1f35e772ac4b957a260f95 100644 (file)
@@ -568,7 +568,7 @@ static int octeon_spi_probe(struct udevice *dev)
                pci_dev_t bdf = dm_pci_get_bdf(dev);
 
                debug("SPI PCI device: %x\n", bdf);
-               priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
+               priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0,
                                            PCI_REGION_MEM);
                /* Add base offset */
                priv->base += 0x1000;
index 4f711de7d8588c95f55df355ca3e15589db0de57..7c34e37b204175b808f18156c24e961fbc8d7b34 100644 (file)
@@ -36,7 +36,7 @@ static int ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr,
                return ret;
 
        hccr = (struct ehci_hccr *)dm_pci_map_bar(dev,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+                       PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        hcor = (struct ehci_hcor *)((uintptr_t) hccr +
                        HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
 
index 6ddc9da704f6bad47757b980c9060faf040828d6..eab0d96637c6b5351d97f9dd7619c488ad650302 100644 (file)
@@ -18,7 +18,7 @@ static int ohci_pci_probe(struct udevice *dev)
 {
        struct ohci_regs *regs;
 
-       regs = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       regs = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        return ohci_register(dev, regs);
 }
 
index 630bc20be1e0dba5e69dbeeceadb1508cad9780e..6ebcbd076376786a33b26abc5438b2d174ebcde0 100644 (file)
@@ -27,7 +27,7 @@ static int xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
        u32 cmd;
 
        hccr = (struct xhci_hccr *)dm_pci_map_bar(dev,
-                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+                       PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_MEM);
        if (!hccr) {
                printf("xhci-pci init cannot map PCI mem bar\n");
                return -EIO;
index 03fa5cb608c47549e7ff14cdbbd6a0caab48db0b..504a7ff7b978f5122c522e59c46836d25cb30858 100644 (file)
@@ -319,7 +319,7 @@ static int virtio_pci_probe(struct udevice *udev)
        uc_priv->device = subdevice;
        uc_priv->vendor = subvendor;
 
-       priv->ioaddr = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, PCI_REGION_IO);
+       priv->ioaddr = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_IO);
        if (!priv->ioaddr)
                return -ENXIO;
        debug("(%s): virtio legacy device reg base %04lx\n",
index 966b84c148e12e8ec26afd87ab56e7978b734165..5175c7ea2fbcf6db6fb339bf2f3a3ce056ea47ef 100644 (file)
@@ -1348,10 +1348,13 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, size_t len,
  *
  * @dev:       Device to check
  * @bar:       Bar register offset (PCI_BASE_ADDRESS_...)
+ * @offset:     Offset from the base to map
+ * @len:        Length to map
  * @flags:     Flags for the region type (PCI_REGION_...)
  * @return: pointer to the virtual address to use or 0 on error
  */
-void *dm_pci_map_bar(struct udevice *dev, int bar, unsigned long flags);
+void *dm_pci_map_bar(struct udevice *dev, int bar, size_t offset, size_t len,
+                    unsigned long flags);
 
 /**
  * dm_pci_find_next_capability() - find a capability starting from an offset
index eff599ef32209e2cde14a2fbc2219d1df8891d55..9ae7840bdd772c127f5d7c39b52a165eebb7a70e 100644 (file)
@@ -268,27 +268,27 @@ static int dm_test_pci_ea(struct unit_test_state *uts)
        ut_asserteq(PCI_CAP_ID_EA_OFFSET, cap);
 
        /* test swap case in BAR 1 */
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_0, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_0, 0, 0, 0);
        ut_assertnonnull(bar);
        *(int *)bar = 2; /* swap upper/lower */
 
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0, 0, 0);
        ut_assertnonnull(bar);
        strcpy(bar, "ea TEST");
        unmap_sysmem(bar);
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_1, 0, 0, 0);
        ut_assertnonnull(bar);
        ut_asserteq_str("EA test", bar);
 
        /* test magic values in BARs2, 4;  BAR 3 is n/a */
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_2, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_2, 0, 0, 0);
        ut_assertnonnull(bar);
        ut_asserteq(PCI_EA_BAR2_MAGIC, *(u32 *)bar);
 
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_3, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_3, 0, 0, 0);
        ut_assertnull(bar);
 
-       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_4, 0);
+       bar = dm_pci_map_bar(swap, PCI_BASE_ADDRESS_4, 0, 0, 0);
        ut_assertnonnull(bar);
        ut_asserteq(PCI_EA_BAR4_MAGIC, *(u32 *)bar);