Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148452894
D15141.id41842.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
D15141.id41842.diff
View Options
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
@@ -542,6 +542,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,10 +1,10 @@
/*-
+ * Copyright (C) 2018 Cavium Inc.
* Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
*
- * This software was developed by Semihalf under
- * the sponsorship of the FreeBSD Foundation.
+ * Developed by Semihalf.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -93,15 +93,52 @@
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 +164,7 @@
{
struct generic_pcie_acpi_softc *sc;
ACPI_HANDLE handle;
+ ACPI_STATUS status;
int error;
sc = device_get_softc(dev);
@@ -144,10 +182,92 @@
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 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;
+
+ 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);
+ }
+
+ 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 void
+pci_host_generic_acpi_apply_quirks(device_t dev)
+{
+ struct pci_host_generic_acpi_quirk_entry *quirk;
+
+ 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 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)
{
@@ -178,6 +298,8 @@
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 +310,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 +443,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 +458,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
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 12:01 AM (8 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29933568
Default Alt Text
D15141.id41842.diff (8 KB)
Attached To
Mode
D15141: Add support for ThunderX2 PCIe
Attached
Detach File
Event Timeline
Log In to Comment