Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148240959
D5294.id13676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D5294.id13676.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
@@ -36,6 +36,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_pcie_identify_ecam(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
@@ -104,6 +104,28 @@
}
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 < MAX_RANGES_TUPLES; 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);
+}
+
+uint64_t
range_addr_pci_to_phys(struct pcie_range *ranges, uint64_t pci_addr)
{
struct pcie_range *r;
Index: sys/arm64/cavium/thunder_pcie_pem.c
===================================================================
--- sys/arm64/cavium/thunder_pcie_pem.c
+++ sys/arm64/cavium/thunder_pcie_pem.c
@@ -93,7 +93,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)
@@ -121,9 +120,13 @@
#define RID_PEM_SPACE 1
+static int thunder_pem_activate_resource(device_t, device_t, int, int,
+ struct resource *);
static struct resource * thunder_pem_alloc_resource(device_t, device_t, int,
int *, rman_res_t, rman_res_t, rman_res_t, u_int);
static int thunder_pem_attach(device_t);
+static int thunder_pem_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
static int thunder_pem_detach(device_t);
static uint64_t thunder_pem_config_reg_read(struct thunder_pem_softc *, int);
static int thunder_pem_link_init(struct thunder_pem_softc *);
@@ -135,6 +138,7 @@
static void thunder_pem_release_all(device_t);
static int thunder_pem_release_resource(device_t, device_t, int, int,
struct resource *);
+static struct rman * thunder_pem_rman(struct thunder_pem_softc *, int);
static void thunder_pem_slix_s2m_regx_acc_modify(struct thunder_pem_softc *,
int, int);
static void thunder_pem_write_config(device_t, u_int, u_int, u_int, u_int,
@@ -157,8 +161,8 @@
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_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_activate_resource, thunder_pem_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, thunder_pem_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
@@ -174,6 +178,7 @@
sizeof(struct thunder_pem_softc));
static devclass_t thunder_pem_devclass;
+extern struct bus_space memmap_bus;
DRIVER_MODULE(thunder_pem, pci, thunder_pem_driver, thunder_pem_devclass, 0, 0);
MODULE_DEPEND(thunder_pem, pci, 1, 1, 1);
@@ -225,6 +230,66 @@
}
static int
+thunder_pem_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ int err;
+ bus_addr_t paddr;
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+ struct thunder_pem_softc *sc;
+
+ if ((err = rman_activate_resource(r)) != 0)
+ return (err);
+
+ sc = device_get_softc(dev);
+
+ /*
+ * If this is a memory resource, map it into the kernel.
+ */
+ if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
+ paddr = (bus_addr_t)rman_get_start(r);
+ psize = (bus_size_t)rman_get_size(r);
+
+ paddr = range_addr_pci_to_phys(sc->ranges, paddr);
+
+ err = bus_space_map(&memmap_bus, paddr, psize, 0, &vaddr);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
+ rman_set_bustag(r, &memmap_bus);
+ rman_set_virtual(r, (void *)vaddr);
+ rman_set_bushandle(r, vaddr);
+ }
+ return (0);
+}
+
+/*
+ * This function is an exact copy of nexus_deactivate_resource()
+ * Keep it up-to-date with all changes in nexus. To be removed
+ * once bus-mapping interface is developed.
+ */
+static int
+thunder_pem_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ bus_size_t psize;
+ bus_space_handle_t vaddr;
+
+ psize = (bus_size_t)rman_get_size(r);
+ vaddr = rman_get_bushandle(r);
+
+ if (vaddr != 0) {
+ bus_space_unmap(&memmap_bus, vaddr, psize);
+ rman_set_virtual(r, NULL);
+ rman_set_bushandle(r, 0);
+ }
+
+ return (rman_deactivate_resource(r));
+}
+
+static int
thunder_pem_identify(device_t dev)
{
struct thunder_pem_softc *sc;
@@ -314,14 +379,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);
@@ -365,24 +422,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);
}
@@ -403,23 +466,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 *
@@ -431,35 +499,30 @@
struct resource *res;
device_t parent_dev;
- switch (type) {
- case SYS_RES_IOPORT:
- rm = &sc->io_rman;
- break;
- case SYS_RES_MEMORY:
- rm = &sc->mem_rman;
- break;
- default:
+ rm = thunder_pem_rman(sc, type);
+ if (rm == NULL) {
/* Find parent device. On ThunderX we know an exact path. */
parent_dev = device_get_parent(device_get_parent(dev));
return (BUS_ALLOC_RESOURCE(parent_dev, dev, type, rid, start,
end, count, flags));
};
- if (RMAN_IS_DEFAULT_RANGE(start, end)) {
- device_printf(dev,
- "Cannot allocate resource with unspecified range\n");
- goto fail;
- }
- /* Translate PCI address to host PHYS */
- if (range_addr_is_pci(sc->ranges, start, count) == 0)
- goto fail;
- start = range_addr_pci_to_phys(sc->ranges, start);
+ if (!RMAN_IS_DEFAULT_RANGE(start, end)) {
+ /*
+ * We might get PHYS addresses here inherited from EFI.
+ * Convert to PCI if necessary.
+ */
+ if (range_addr_is_phys(sc->ranges, start, count)) {
+ start = range_addr_phys_to_pci(sc->ranges, start);
end = start + count - 1;
+ }
+
+ }
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);
}
@@ -503,6 +566,22 @@
return (rman_release_resource(res));
}
+static struct rman *
+thunder_pem_rman(struct thunder_pem_softc *sc, int type)
+{
+
+ switch (type) {
+ case SYS_RES_IOPORT:
+ return (&sc->io_rman);
+ case SYS_RES_MEMORY:
+ return (&sc->mem_rman);
+ default:
+ break;
+ }
+
+ return (NULL);
+}
+
static int
thunder_pem_probe(device_t dev)
{
@@ -529,6 +608,9 @@
struct thunder_pem_softc *sc;
int error;
int rid;
+ int tuple;
+ uint64_t base, size;
+ struct rman *rman;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -601,16 +683,42 @@
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);
+ sc->ranges[0].flags = SYS_RES_MEMORY;
/* 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);
+ sc->ranges[1].flags = SYS_RES_IOPORT;
+
+ for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
+ base = sc->ranges[tuple].pci_base;
+ size = sc->ranges[tuple].size;
+ if (size == 0)
+ continue; /* empty range element */
+
+ rman = thunder_pem_rman(sc, sc->ranges[tuple].flags);
+ if (rman != NULL)
+ error = rman_manage_region(rman, base,
+ base + size - 1);
+ else
+ error = EINVAL;
+ 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, Flags:0x%jx\n",
+ sc->ranges[tuple].pci_base,
+ sc->ranges[tuple].phys_base,
+ sc->ranges[tuple].size,
+ sc->ranges[tuple].flags);
+ }
+ }
if (thunder_pem_init(sc)) {
device_printf(dev, "Failure during PEM init\n");
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 17, 5:54 PM (16 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29838639
Default Alt Text
D5294.id13676.diff (10 KB)
Attached To
Mode
D5294: Improve ThunderX PEM driver to work on pass2 revision
Attached
Detach File
Event Timeline
Log In to Comment