dm_pci_write_config32(dev, bar, addr);
}
-static int _dm_pci_bus_to_phys(struct udevice *ctlr,
- pci_addr_t bus_addr, unsigned long flags,
+static int _dm_pci_bus_to_phys(struct udevice *ctlr, pci_addr_t bus_addr,
+ size_t len, unsigned long flags,
unsigned long skip_mask, phys_addr_t *pa)
{
struct pci_controller *hose = dev_get_uclass_priv(ctlr);
struct pci_region *res;
+ pci_addr_t offset;
int i;
if (hose->region_count == 0) {
if (res->flags & skip_mask)
continue;
- if (bus_addr >= res->bus_start &&
- (bus_addr - res->bus_start) < res->size) {
- *pa = (bus_addr - res->bus_start + res->phys_start);
- return 0;
- }
+ if (bus_addr < res->bus_start)
+ continue;
+
+ offset = bus_addr - res->bus_start;
+ if (offset >= res->size)
+ continue;
+
+ if (len > res->size - offset)
+ continue;
+
+ *pa = res->phys_start + offset;
+ return 0;
}
return 1;
}
phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t bus_addr,
- unsigned long flags)
+ size_t len, unsigned long flags)
{
phys_addr_t phys_addr = 0;
struct udevice *ctlr;
* on matches that don't have PCI_REGION_SYS_MEMORY set
*/
if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
- ret = _dm_pci_bus_to_phys(ctlr, bus_addr,
+ ret = _dm_pci_bus_to_phys(ctlr, bus_addr, len,
flags, PCI_REGION_SYS_MEMORY,
&phys_addr);
if (!ret)
return phys_addr;
}
- ret = _dm_pci_bus_to_phys(ctlr, bus_addr, flags, 0, &phys_addr);
+ ret = _dm_pci_bus_to_phys(ctlr, bus_addr, len, flags, 0, &phys_addr);
if (ret)
puts("pci_hose_bus_to_phys: invalid physical address\n");
}
static int _dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
- unsigned long flags, unsigned long skip_mask,
- pci_addr_t *ba)
+ size_t len, unsigned long flags,
+ unsigned long skip_mask, pci_addr_t *ba)
{
struct pci_region *res;
struct udevice *ctlr;
- pci_addr_t bus_addr;
+ phys_addr_t offset;
int i;
struct pci_controller *hose;
if (res->flags & skip_mask)
continue;
- bus_addr = phys_addr - res->phys_start + res->bus_start;
+ if (phys_addr < res->phys_start)
+ continue;
- if (bus_addr >= res->bus_start &&
- (bus_addr - res->bus_start) < res->size) {
- *ba = bus_addr;
- return 0;
- }
+ offset = phys_addr - res->phys_start;
+ if (offset >= res->size)
+ continue;
+
+ if (len > res->size - offset)
+ continue;
+
+ *ba = res->bus_start + offset;
+ return 0;
}
return 1;
}
pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t phys_addr,
- unsigned long flags)
+ size_t len, unsigned long flags)
{
pci_addr_t bus_addr = 0;
int ret;
* on matches that don't have PCI_REGION_SYS_MEMORY set
*/
if ((flags & PCI_REGION_TYPE) == PCI_REGION_MEM) {
- ret = _dm_pci_phys_to_bus(dev, phys_addr, flags,
+ ret = _dm_pci_phys_to_bus(dev, phys_addr, len, flags,
PCI_REGION_SYS_MEMORY, &bus_addr);
if (!ret)
return bus_addr;
}
- ret = _dm_pci_phys_to_bus(dev, phys_addr, flags, 0, &bus_addr);
+ ret = _dm_pci_phys_to_bus(dev, phys_addr, len, flags, 0, &bus_addr);
if (ret)
puts("pci_hose_phys_to_bus: invalid physical address\n");
u32 dm_pci_read_bar32(const struct udevice *dev, int barnum);
/**
- * dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
+ * dm_pci_bus_to_phys() - convert a PCI bus address range to a physical address
*
* @dev: Device containing the PCI address
* @addr: PCI address to convert
+ * @len: Length of the address range
* @flags: Flags for the region type (PCI_REGION_...)
* Return: physical address corresponding to that PCI bus address
*/
-phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr,
+phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, size_t len,
unsigned long flags);
/**
*
* @dev: Device containing the bus address
* @addr: Physical address to convert
+ * @len: Length of the address range
* @flags: Flags for the region type (PCI_REGION_...)
* Return: PCI bus address corresponding to that physical address
*/
-pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
+pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, size_t len,
unsigned long flags);
/**
int dm_pci_flr(struct udevice *dev);
#define dm_pci_virt_to_bus(dev, addr, flags) \
- dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
+ dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), 0, (flags))
#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
- map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \
+ map_physmem(dm_pci_bus_to_phys(dev, (addr), (len), (flags)), \
(len), (map_flags))
#define dm_pci_phys_to_mem(dev, addr) \
- dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+ dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_MEM)
#define dm_pci_mem_to_phys(dev, addr) \
- dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+ dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_MEM)
#define dm_pci_phys_to_io(dev, addr) \
- dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+ dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_IO)
#define dm_pci_io_to_phys(dev, addr) \
- dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+ dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_IO)
#define dm_pci_virt_to_mem(dev, addr) \
dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)