Page MenuHomeFreeBSD

D15141.id43643.diff
No OneTemporary

D15141.id43643.diff

Index: sys/arm64/include/cpu.h
===================================================================
--- sys/arm64/include/cpu.h
+++ sys/arm64/include/cpu.h
@@ -79,6 +79,7 @@
#define CPU_IMPL_INTEL 0x69
#define CPU_PART_THUNDER 0x0A1
+#define CPU_PART_THUNDERX2 0x0AF
#define CPU_PART_FOUNDATION 0xD00
#define CPU_PART_CORTEX_A35 0xD04
#define CPU_PART_CORTEX_A53 0xD03
@@ -91,6 +92,8 @@
#define CPU_REV_THUNDER_1_0 0x00
#define CPU_REV_THUNDER_1_1 0x01
+#define CPU_REV_THUNDERX2_0 0x00
+
#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
Index: sys/dev/acpica/acpi_resource.c
===================================================================
--- sys/dev/acpica/acpi_resource.c
+++ sys/dev/acpica/acpi_resource.c
@@ -560,6 +560,9 @@
if (cp == NULL)
return;
+ while (bus_get_resource_start(dev, SYS_RES_MEMORY, cp->ar_nmem))
+ cp->ar_nmem++;
+
bus_set_resource(dev, SYS_RES_MEMORY, cp->ar_nmem++, base, length);
}
Index: sys/dev/pci/pci_host_generic.c
===================================================================
--- sys/dev/pci/pci_host_generic.c
+++ sys/dev/pci/pci_host_generic.c
@@ -71,7 +71,7 @@
/* Forward prototypes */
-static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
u_int func, u_int reg, int bytes);
static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
u_int func, u_int reg, uint32_t val, int bytes);
@@ -107,7 +107,7 @@
return (error);
rid = 0;
- sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
+ sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_SHAREABLE);
if (sc->res == NULL) {
device_printf(dev, "could not map memory.\n");
return (ENXIO);
@@ -137,7 +137,7 @@
return (0);
}
-static uint32_t
+uint32_t
generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
u_int func, u_int reg, int bytes)
{
@@ -226,8 +226,7 @@
sc = device_get_softc(dev);
if (index == PCIB_IVAR_BUS) {
- /* this pcib adds only pci bus 0 as child */
- secondary_bus = 0;
+ secondary_bus = sc->ecam * 0x80;
*result = secondary_bus;
return (0);
Index: sys/dev/pci/pci_host_generic_acpi.c
===================================================================
--- sys/dev/pci/pci_host_generic_acpi.c
+++ sys/dev/pci/pci_host_generic_acpi.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (C) 2018 Cavium Inc.
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
@@ -93,15 +94,48 @@
ACPI_BUFFER ap_prt; /* interrupt routing table */
};
+typedef void (*pci_host_generic_acpi_quirk_function)(device_t);
+
+struct pci_host_generic_acpi_quirk_entry {
+ int impl;
+ int part;
+ int var;
+ int rev;
+ pci_host_generic_acpi_quirk_function func;
+};
+
+struct pci_host_generic_acpi_block_entry {
+ int impl;
+ int part;
+ int var;
+ int rev;
+ int bus;
+ int slot;
+};
+
/* Forward prototypes */
static int generic_pcie_acpi_probe(device_t dev);
-static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
+uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
u_int func, u_int reg, int bytes);
-static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
- u_int func, u_int reg, uint32_t val, int bytes);
-static int generic_pcie_release_resource(device_t dev, device_t child,
- int type, int rid, struct resource *res);
+static ACPI_STATUS pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *, void *);
+static void pci_host_generic_acpi_apply_quirks(device_t);
+static void thunderx2_ahci_bar_quirk(device_t);
+static void thunderx2_ecam_base_quirk(device_t);
+
+struct pci_host_generic_acpi_quirk_entry pci_host_generic_acpi_quirks[] =
+{
+ {CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0, 0, thunderx2_ecam_base_quirk},
+ {CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0, 0, thunderx2_ahci_bar_quirk},
+ {0, 0, 0, 0, NULL}
+};
+
+struct pci_host_generic_acpi_block_entry pci_host_generic_acpi_blocked[] =
+{
+ /* ThunderX2 AHCI on second socket */
+ {CPU_IMPL_CAVIUM, CPU_PART_THUNDERX2, 0, 0, 0x80, 0x10},
+ {0, 0, 0, 0, 0, 0}
+};
static int
generic_pcie_acpi_probe(device_t dev)
@@ -127,6 +161,7 @@
{
struct generic_pcie_acpi_softc *sc;
ACPI_HANDLE handle;
+ ACPI_STATUS status;
int error;
sc = device_get_softc(dev);
@@ -144,40 +179,108 @@
if (error != 0)
return (error);
+ status = AcpiWalkResources(handle, "_CRS",
+ pci_host_generic_acpi_parse_resource, (void *)dev);
+
+ if (ACPI_FAILURE(status))
+ return (ENXIO);
+
device_add_child(dev, "pci", -1);
+ pci_host_generic_acpi_apply_quirks(dev);
+
return (bus_generic_attach(dev));
}
-static int
-generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin)
+static ACPI_STATUS
+pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg)
{
+ device_t dev = (device_t)arg;
struct generic_pcie_acpi_softc *sc;
+ rman_res_t min, max;
+ int error;
- sc = device_get_softc(bus);
+ switch (res->Type) {
+ case ACPI_RESOURCE_TYPE_ADDRESS32:
+ min = (rman_res_t)res->Data.Address32.Address.Minimum;
+ max = (rman_res_t)res->Data.Address32.Address.Maximum;
+ break;
+ case ACPI_RESOURCE_TYPE_ADDRESS64:
+ min = (rman_res_t)res->Data.Address64.Address.Minimum;
+ max = (rman_res_t)res->Data.Address64.Address.Maximum;
+ break;
+ default:
+ return (AE_OK);
+ }
- return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt));
+ sc = device_get_softc(dev);
+
+ error = rman_manage_region(&sc->base.mem_rman, min, max);
+ if (error) {
+ device_printf(dev, "unable to allocate %lx-%lx range\n", min, max);
+ return (AE_NOT_FOUND);
+ }
+ device_printf(dev, "allocating %lx-%lx range\n", min, max);
+
+ return (AE_OK);
}
-static struct rman *
-generic_pcie_acpi_rman(struct generic_pcie_acpi_softc *sc, int type)
+static void
+pci_host_generic_acpi_apply_quirks(device_t dev)
{
+ struct pci_host_generic_acpi_quirk_entry *quirk;
- switch (type) {
- case SYS_RES_IOPORT:
- return (&sc->base.io_rman);
- case SYS_RES_MEMORY:
- return (&sc->base.mem_rman);
- default:
+ quirk = pci_host_generic_acpi_quirks;
+ while (1) {
+ if (quirk->impl == 0)
+ break;
+
+ if (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK,
+ quirk->impl, quirk->part, quirk->var, quirk->rev) &&
+ quirk->func != NULL)
+ quirk->func(dev);
+
+ quirk++;
+ }
+}
+
+static uint32_t
+pci_host_generic_acpi_read_config(device_t dev, u_int bus, u_int slot,
+ u_int func, u_int reg, int bytes)
+{
+ struct pci_host_generic_acpi_block_entry *block;
+
+ block = pci_host_generic_acpi_blocked;
+ while (1) {
+ if (block->impl == 0)
break;
+
+ if (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK,
+ block->impl, block->part, block->var, block->rev) &&
+ block->bus == bus && block->slot == slot)
+ return (~0);
+
+ block++;
}
- return (NULL);
+ return generic_pcie_read_config(dev, bus, slot, func, reg, bytes);
+}
+
+static int
+generic_pcie_acpi_route_interrupt(device_t bus, device_t dev, int pin)
+{
+ struct generic_pcie_acpi_softc *sc;
+
+ sc = device_get_softc(bus);
+
+ return (acpi_pcib_route_interrupt(bus, dev, pin, &sc->ap_prt));
}
static struct resource *
pci_host_generic_acpi_alloc_resource(device_t dev, device_t child, int type,
int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
{
+ struct resource *res = NULL;
+
#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
struct generic_pcie_acpi_softc *sc;
@@ -188,8 +291,15 @@
}
#endif
- return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
- count, flags));
+ if (type == SYS_RES_MEMORY)
+ res = pci_host_generic_core_alloc_resource(dev, child, type,
+ rid, start, end, count, flags);
+
+ if (res == NULL)
+ res = bus_generic_alloc_resource(dev, child, type, rid, start, end,
+ count, flags);
+
+ return (res);
}
static int
@@ -314,6 +424,7 @@
DEVMETHOD(pcib_alloc_msi, generic_pcie_acpi_alloc_msi),
DEVMETHOD(pcib_release_msi, generic_pcie_acpi_release_msi),
DEVMETHOD(pcib_alloc_msix, generic_pcie_acpi_alloc_msix),
+ DEVMETHOD(pcib_read_config, pci_host_generic_acpi_read_config),
DEVMETHOD(pcib_release_msix, generic_pcie_acpi_release_msix),
DEVMETHOD(pcib_map_msi, generic_pcie_acpi_map_msi),
DEVMETHOD(pcib_get_id, generic_pcie_acpi_get_id),
@@ -328,3 +439,33 @@
DRIVER_MODULE(pcib, acpi, generic_pcie_acpi_driver, generic_pcie_acpi_devclass,
0, 0);
+
+static void thunderx2_ahci_bar_quirk(device_t dev)
+{
+
+ /*
+ * XXX:
+ * On ThunderX2, AHCI BAR2 address is wrong. It needs to precisely
+ * match the one described in datasheet. Fixup it unconditionally.
+ */
+ if (device_get_unit(dev) == 0) {
+ device_printf(dev, "running AHCI BAR fixup\n");
+ PCIB_WRITE_CONFIG(dev, 0, 16, 0, 0x18, 0x01440000, 4);
+ PCIB_WRITE_CONFIG(dev, 0, 16, 0, 0x1c, 0x40, 4);
+ PCIB_WRITE_CONFIG(dev, 0, 16, 1, 0x18, 0x01450000, 4);
+ PCIB_WRITE_CONFIG(dev, 0, 16, 1, 0x1c, 0x40, 4);
+ }
+}
+
+static void thunderx2_ecam_base_quirk(device_t dev)
+{
+ struct generic_pcie_acpi_softc *sc;
+
+ sc = device_get_softc(dev);
+ /*
+ * XXX:
+ * On Thunder X2, pcib16 is a beginning of second ECAM domain.
+ */
+ if (device_get_unit(dev) == 16)
+ sc->base.ecam = 1;
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 22, 11:04 AM (12 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35362038
Default Alt Text
D15141.id43643.diff (9 KB)

Event Timeline