Page MenuHomeFreeBSD

D5294.id13345.diff
No OneTemporary

D5294.id13345.diff

Index: sys/arm64/cavium/thunder_pcie_common.h
===================================================================
--- sys/arm64/cavium/thunder_pcie_common.h
+++ sys/arm64/cavium/thunder_pcie_common.h
@@ -53,6 +53,7 @@
uint32_t range_addr_is_pci(struct pcie_range *, uint64_t, uint64_t);
uint32_t range_addr_is_phys(struct pcie_range *, uint64_t, uint64_t);
+uint64_t range_addr_phys_to_pci(struct pcie_range *, uint64_t);
uint64_t range_addr_pci_to_phys(struct pcie_range *, uint64_t);
int thunder_common_alloc_msi(device_t, device_t, int, int, int *);
int thunder_common_alloc_msix(device_t, device_t, int *);
Index: sys/arm64/cavium/thunder_pcie_common.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_common.c
+++ sys/arm64/cavium/thunder_pcie_common.c
@@ -109,3 +109,25 @@
return (0);
}
+uint64_t
+range_addr_phys_to_pci(struct pcie_range *ranges, uint64_t phys_addr)
+{
+ struct pcie_range *r;
+ uint64_t offset;
+ int tuple;
+
+ /* Find physical address corresponding to given bus address */
+ for (tuple = 0; tuple < RANGES_TUPLES_MAX; tuple++) {
+ r = &ranges[tuple];
+ if (phys_addr >= r->phys_base &&
+ phys_addr < (r->phys_base + r->size)) {
+ /* Given phys addr is in this range.
+ * Translate phys addr to bus addr.
+ */
+ offset = phys_addr - r->phys_base;
+ return (r->pci_base + offset);
+ }
+ }
+ return (0);
+}
+
Index: sys/arm64/cavium/thunder_pcie_pem.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_pem.c
+++ sys/arm64/cavium/thunder_pcie_pem.c
@@ -43,6 +43,8 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
+#include <dev/pci/pcib_private.h>
+#include <dev/pci/pci_private.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -83,7 +85,6 @@
#define SLIX_S2M_REGX_ACC_SPACING 0x001000000000UL
#define SLI_BASE 0x880000000000UL
#define SLI_WINDOW_SPACING 0x004000000000UL
-#define SLI_WINDOW_SIZE 0x0000FF000000UL
#define SLI_PCI_OFFSET 0x001000000000UL
#define SLI_NODE_SHIFT (44)
#define SLI_NODE_MASK (3)
@@ -144,6 +145,8 @@
static void thunder_pem_write_config(device_t, u_int, u_int, u_int, u_int,
uint32_t, int);
static int thunder_pem_write_ivar(device_t, device_t, int, uintptr_t);
+static int thunder_pem_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r);
/* Global handlers for SLI interface */
static bus_space_handle_t sli0_s2m_regx_base = 0;
@@ -161,7 +164,7 @@
DEVMETHOD(bus_write_ivar, thunder_pem_write_ivar),
DEVMETHOD(bus_alloc_resource, thunder_pem_alloc_resource),
DEVMETHOD(bus_release_resource, thunder_pem_release_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_activate_resource, thunder_pem_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -227,6 +230,49 @@
}
static int
+thunder_pem_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ pci_addr_t map, testval, start, start_conv;
+ struct thunder_pem_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+
+ /* Read BAR manually to get resource address and size */
+ pci_read_bar(child, rid, &map, &testval, NULL);
+
+ /* Mask the information bits */
+ if (PCI_BAR_MEM(map))
+ map &= PCIM_BAR_MEM_BASE;
+ else
+ map &= PCIM_BAR_IO_BASE;
+ start_conv = start = map;
+
+ /* Translate PHYS start address to host PCI if necessary */
+ if (range_addr_is_pci(sc->ranges, start, 1) == 0) {
+ if (range_addr_is_phys(sc->ranges, start, 1) == 0)
+ break;
+ start_conv = range_addr_phys_to_pci(sc->ranges, start);
+ }
+ if (start == start_conv)
+ break;
+ if (bootverbose)
+ device_printf(dev, "translate rid[%x] 0x%lx->0x%lx\n",
+ rid, start, start_conv);
+ pci_write_bar(child, pci_find_bar(child, rid), start_conv);
+ break;
+ default:
+ break;
+ }
+
+ return (bus_generic_activate_resource(dev, child, type, rid, r));
+}
+
+static int
thunder_pem_identify(device_t dev)
{
struct thunder_pem_softc *sc;
@@ -316,14 +362,6 @@
return retval;
}
- retval = bus_space_map(sc->reg_bst, sc->sli_window_base,
- SLI_WINDOW_SIZE, 0, &sc->pem_sli_base);
- if (retval) {
- device_printf(sc->dev,
- "Unable to map RC%d pem_addr base address", sc->id);
- return (ENOMEM);
- }
-
/* To support 32-bit PCIe devices, set S2M_REGx_ACC[BA]=0x0 */
for (i = 0; i < SLI_ACC_REG_CNT; i++) {
thunder_pem_slix_s2m_regx_acc_modify(sc, sc->sli_group, i);
@@ -367,24 +405,30 @@
/* Calculate offset */
offset = (bus << PEM_BUS_SHIFT) | (slot << PEM_SLOT_SHIFT) |
- (func << PEM_FUNC_SHIFT) | reg;
+ (func << PEM_FUNC_SHIFT);
t = sc->reg_bst;
h = sc->pem_sli_base;
+ bus_space_map(sc->reg_bst, sc->sli_window_base + offset,
+ PCIE_REGMAX, 0, &h);
+
switch (bytes) {
case 1:
- data = bus_space_read_1(t, h, offset);
+ data = bus_space_read_1(t, h, reg);
break;
case 2:
- data = le16toh(bus_space_read_2(t, h, offset));
+ data = le16toh(bus_space_read_2(t, h, reg));
break;
case 4:
- data = le32toh(bus_space_read_4(t, h, offset));
+ data = le32toh(bus_space_read_4(t, h, reg));
break;
default:
- return (~0U);
+ data = ~0U;
+ break;
}
+ bus_space_unmap(sc->reg_bst, h, PCIE_REGMAX);
+
return (data);
}
@@ -405,23 +449,28 @@
/* Calculate offset */
offset = (bus << PEM_BUS_SHIFT) | (slot << PEM_SLOT_SHIFT) |
- (func << PEM_FUNC_SHIFT) | reg;
+ (func << PEM_FUNC_SHIFT);
t = sc->reg_bst;
h = sc->pem_sli_base;
+ bus_space_map(sc->reg_bst, sc->sli_window_base + offset,
+ PCIE_REGMAX, 0, &h);
+
switch (bytes) {
case 1:
- bus_space_write_1(t, h, offset, val);
+ bus_space_write_1(t, h, reg, val);
break;
case 2:
- bus_space_write_2(t, h, offset, htole16(val));
+ bus_space_write_2(t, h, reg, htole16(val));
break;
case 4:
- bus_space_write_4(t, h, offset, htole32(val));
+ bus_space_write_4(t, h, reg, htole32(val));
break;
default:
- return;
+ break;
}
+
+ bus_space_unmap(sc->reg_bst, h, PCIE_REGMAX);
}
static struct resource *
@@ -453,15 +502,18 @@
goto fail;
}
- /* Translate PCI address to host PHYS */
+ /* Translate PCI address to host PHYS if necessary */
+ if (range_addr_is_phys(sc->ranges, start, count) != 0)
+ goto is_good;
if (range_addr_is_pci(sc->ranges, start, count) == 0)
goto fail;
start = range_addr_pci_to_phys(sc->ranges, start);
end = start + count - 1;
+is_good:
if (bootverbose) {
device_printf(dev,
- "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
+ "thunder_pem_alloc_resource: start=%#lx, end=%#lx, count=%#lx\n",
start, end, count);
}
@@ -529,6 +581,8 @@
struct thunder_pem_softc *sc;
int error;
int rid;
+ int tuple;
+ uint64_t base, size;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -588,16 +642,34 @@
sc->ranges[0].size = PCI_MEMORY_SIZE;
sc->ranges[0].phys_base = sc->sli_window_base + SLI_PCI_OFFSET +
sc->ranges[0].pci_base;
- rman_manage_region(&sc->mem_rman, sc->ranges[0].phys_base,
- sc->ranges[0].phys_base + sc->ranges[0].size - 1);
/* Fill IO window */
sc->ranges[1].pci_base = PCI_IO_BASE;
sc->ranges[1].size = PCI_IO_SIZE;
sc->ranges[1].phys_base = sc->sli_window_base + SLI_PCI_OFFSET +
sc->ranges[1].pci_base;
- rman_manage_region(&sc->io_rman, sc->ranges[1].phys_base,
- sc->ranges[1].phys_base + sc->ranges[1].size - 1);
+
+ for (tuple = 0; tuple < RANGES_TUPLES_MAX; tuple++) {
+ base = sc->ranges[tuple].phys_base;
+ size = sc->ranges[tuple].size;
+ if ((base == 0) || (size == 0))
+ continue; /* empty range element */
+
+ error = rman_manage_region(&sc->mem_rman, base, base + size - 1);
+ if (error) {
+ device_printf(dev,
+ "rman_manage_region() failed. error = %d\n", error);
+ rman_fini(&sc->mem_rman);
+ return (error);
+ }
+ if (bootverbose) {
+ device_printf(dev,
+ "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
+ sc->ranges[0].pci_base,
+ sc->ranges[0].phys_base,
+ sc->ranges[0].size);
+ }
+ }
if (thunder_pem_init(sc)) {
device_printf(dev, "Failure during PEM init\n");

File Metadata

Mime Type
text/plain
Expires
Wed, May 20, 1:29 AM (12 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33333635
Default Alt Text
D5294.id13345.diff (8 KB)

Event Timeline