Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157176519
D5294.id13345.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D5294.id13345.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5294: Improve ThunderX PEM driver to work on pass2 revision
Attached
Detach File
Event Timeline
Log In to Comment