diff --git a/drivers/devicetree/fdt_pci.c b/drivers/devicetree/fdt_pci.c index 44ebcb27812..96ce7140958 100644 --- a/drivers/devicetree/fdt_pci.c +++ b/drivers/devicetree/fdt_pci.c @@ -118,22 +118,26 @@ int fdt_pci_ecam_register(FAR const void *fdt) if ((type & FDT_PCI_TYPE_MASK) == FDT_PCI_TYPE_IO) { - io.start = fdt_ld_by_cells(ranges + na, pna); + io.start = fdt_ld_by_cells(ranges + 1, na -1); io.end = io.start + fdt_ld_by_cells(ranges + na + pna, ns); + io.offset = fdt_ld_by_cells(ranges + na, pna) - io.start; } else if ((type & FDT_PCI_PREFTCH) == FDT_PCI_PREFTCH) { - prefetch.start = fdt_ld_by_cells(ranges + na, pna); + prefetch.start = fdt_ld_by_cells(ranges + 1, na - 1); prefetch.end = prefetch.start + fdt_ld_by_cells(ranges + na + pna, ns); + prefetch.offset = fdt_ld_by_cells(ranges + na, pna) - + prefetch.start; } else if (((type & FDT_PCI_TYPE_MEM32) == FDT_PCI_TYPE_MEM32 && sizeof(uintptr_t) == 4) || ((type & FDT_PCI_TYPE_MEM64) == FDT_PCI_TYPE_MEM64 && sizeof(uintptr_t) == 8)) { - mem.start = fdt_ld_by_cells(ranges + na, pna); + mem.start = fdt_ld_by_cells(ranges + 1, na - 1); mem.end = mem.start + fdt_ld_by_cells(ranges + na + pna, ns); + mem.offset = fdt_ld_by_cells(ranges + na, pna) - mem.start; } } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6f2714dfa2a..869a8d797a4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -672,14 +672,19 @@ static uint32_t pci_size(uint32_t base, uint32_t maxbase, uint32_t mask) * prefetchable MEM, and add this dev to the device list. * * Input Parameters: - * dev - The PCI device be found - * max_bar - Max bar number(6 or 2) + * dev - The PCI device be found + * max_bar - Max bar number(6 or 2) * rom_addr - The pci device rom addr + * io - The pci bus io resource + * mem - The pci bus mem resource + * mem_pref - The pci bus mem_pref resource * ****************************************************************************/ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, - uint8_t rom_addr) + uint8_t rom_addr, FAR struct pci_resource_s *io, + FAR struct pci_resource_s *mem, + FAR struct pci_resource_s *mem_pref) { int bar; uint32_t orig; @@ -720,7 +725,7 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, size = pci_size(orig, mask, 0xfffffffe); flags = PCI_RESOURCE_IO; - res = &dev->bus->ctrl->io; + res = io; } else if ((mask & PCI_BASE_ADDRESS_MEM_PREFETCH) && pci_resource_size(&dev->bus->ctrl->mem_pref)) @@ -729,7 +734,7 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, size = pci_size(orig, mask, 0xfffffff0); flags = PCI_RESOURCE_MEM | PCI_RESOURCE_PREFETCH; - res = &dev->bus->ctrl->mem_pref; + res = mem_pref; } else { @@ -737,7 +742,7 @@ static void pci_setup_device(FAR struct pci_device_s *dev, int max_bar, size = pci_size(orig, mask, 0xfffffff0); flags = PCI_RESOURCE_MEM; - res = &dev->bus->ctrl->mem; + res = mem; } if (size == 0) @@ -963,6 +968,9 @@ static void pci_scan_bus(FAR struct pci_bus_s *bus) { FAR struct pci_device_s *dev; FAR struct pci_bus_s *child_bus; + struct pci_resource_s mem_pref; + struct pci_resource_s mem; + struct pci_resource_s io; unsigned int devfn; uint32_t l; uint32_t class; @@ -971,6 +979,10 @@ static void pci_scan_bus(FAR struct pci_bus_s *bus) pciinfo("pci_scan_bus for bus %d\n", bus->number); + memcpy(&io, &bus->ctrl->io, sizeof(struct pci_resource_s)); + memcpy(&mem, &bus->ctrl->mem, sizeof(struct pci_resource_s)); + memcpy(&mem_pref, &bus->ctrl->mem_pref, sizeof(struct pci_resource_s)); + for (devfn = 0; devfn < 0xff; ++devfn) { if (PCI_FUNC(devfn) && !is_multi) @@ -1027,7 +1039,7 @@ static void pci_scan_bus(FAR struct pci_bus_s *bus) goto bad; } - pci_setup_device(dev, 6, PCI_ROM_ADDRESS); + pci_setup_device(dev, 6, PCI_ROM_ADDRESS, &io, &mem, &mem_pref); pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); @@ -1056,7 +1068,7 @@ static void pci_scan_bus(FAR struct pci_bus_s *bus) pci_scan_bus(child_bus); pci_postsetup_bridge(dev); - pci_setup_device(dev, 2, PCI_ROM_ADDRESS1); + pci_setup_device(dev, 2, PCI_ROM_ADDRESS1, &io, &mem, &mem_pref); break; default: diff --git a/drivers/pci/pci_ecam.c b/drivers/pci/pci_ecam.c index 31929fc36aa..011e2c0d027 100644 --- a/drivers/pci/pci_ecam.c +++ b/drivers/pci/pci_ecam.c @@ -65,6 +65,8 @@ static int pci_ecam_write_io(FAR struct pci_bus_s *bus, uintptr_t addr, static int pci_ecam_get_irq(FAR struct pci_bus_s *bus, uint32_t devfn, uint8_t line, uint8_t pin); +static uintptr_t pci_ecam_map(FAR struct pci_bus_s *bus, uintptr_t start, + uintptr_t end); #ifdef CONFIG_PCI_MSIX static int pci_ecam_alloc_irq(FAR struct pci_bus_s *bus, uint32_t devfn, FAR int *irq, int num); @@ -98,6 +100,7 @@ static const struct pci_ops_s g_pci_ecam_ops = .read_io = pci_ecam_read_io, .write_io = pci_ecam_write_io, .get_irq = pci_ecam_get_irq, + .map = pci_ecam_map, #ifdef CONFIG_PCI_MSIX .alloc_irq = pci_ecam_alloc_irq, .release_irq = pci_ecam_release_irq, @@ -436,6 +439,45 @@ static int pci_ecam_get_irq(FAR struct pci_bus_s *bus, uint32_t devfn, return up_get_legacy_irq(devfn, line, pin); } +/**************************************************************************** + * Name: pci_ecam_map + * + * Description: + * Map pci addr to cpu addr. + * + * Input Parameters: + * bus - Bus that PCI device resides + * start - The pci device start pci addr + * end - The pci device end pci addr + * + * Returned Value: + * Return pci device cpu addr + * + ****************************************************************************/ + +static uintptr_t pci_ecam_map(FAR struct pci_bus_s *bus, uintptr_t start, + uintptr_t end) +{ + FAR struct pci_controller_s *ctrl = bus->ctrl; + + if (start >= ctrl->io.start && end < ctrl->io.end) + { + return start + ctrl->io.offset; + } + + if (start >= ctrl->mem.start && end < ctrl->mem.end) + { + return start + ctrl->mem.offset; + } + + if (start >= ctrl->mem_pref.start && end < ctrl->mem_pref.end) + { + return start + ctrl->mem_pref.offset; + } + + return 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/include/nuttx/pci/pci.h b/include/nuttx/pci/pci.h index f1f19442880..07929342f22 100644 --- a/include/nuttx/pci/pci.h +++ b/include/nuttx/pci/pci.h @@ -238,6 +238,7 @@ struct pci_resource_s { uintptr_t start; uintptr_t end; + uintptr_t offset; unsigned int flags; };