Page MenuHomeFreeBSD

D3118.id7045.diff
No OneTemporary

D3118.id7045.diff

Index: sys/arm64/arm64/gic_v3_its.c
===================================================================
--- sys/arm64/arm64/gic_v3_its.c
+++ sys/arm64/arm64/gic_v3_its.c
@@ -44,6 +44,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <vm/vm.h>
@@ -84,6 +85,8 @@
MALLOC_DEFINE(M_GIC_V3_ITS, "GICv3 ITS", GIC_V3_ITS_DEVSTR);
+typedef uint32_t (*its_devid_func_t)(device_t);
+
static int its_alloc_tables(struct gic_v3_its_softc *);
static void its_free_tables(struct gic_v3_its_softc *);
static void its_init_commandq(struct gic_v3_its_softc *);
@@ -98,12 +101,19 @@
static void its_cmd_mapi(struct gic_v3_its_softc *, struct its_dev *, uint32_t);
static void its_cmd_inv(struct gic_v3_its_softc *, struct its_dev *, uint32_t);
static void its_cmd_invall(struct gic_v3_its_softc *, struct its_col *);
+static uint32_t its_quirk_devid_thunder(device_t);
static void lpi_init_conftable(struct gic_v3_its_softc *);
static void lpi_bitmap_init(struct gic_v3_its_softc *);
static void lpi_init_cpu(struct gic_v3_its_softc *);
static int lpi_config_cpu(struct gic_v3_its_softc *);
+struct its_quirks {
+ uint64_t cpuid;
+ uint64_t cpuid_mask;
+ its_devid_func_t devid_func;
+};
+
const char *its_ptab_cache[] = {
[GITS_BASER_CACHE_NCNB] = "(NC,NB)",
[GITS_BASER_CACHE_NC] = "(NC)",
@@ -133,6 +143,19 @@
[GITS_BASER_TYPE_RES7] = "Reserved (7)",
};
+static struct its_quirks its_quirks[] = {
+ {
+ .cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0),
+ .cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK,
+ .devid_func = its_quirk_devid_thunder,
+ },
+ {
+ .cpuid = 0,
+ .cpuid_mask = 0,
+ .devid_func = NULL,
+ }
+};
+
static struct gic_v3_its_softc *its_sc;
#define gic_its_read(sc, len, reg) \
@@ -141,6 +164,68 @@
#define gic_its_write(sc, len, reg, val) \
bus_write_##len(&sc->its_res[0], reg, val)
+static uint32_t
+its_quirk_devid_thunder(device_t pci_dev)
+{
+ int bsf;
+ uint32_t bus;
+
+ bus = pci_get_bus(pci_dev);
+
+ bsf = PCI_RID(pci_get_bus(pci_dev), pci_get_slot(pci_dev),
+ pci_get_function(pci_dev));
+
+ /* ECAM is on bus=0 */
+ if (bus == 0) {
+ return ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) |
+ bsf);
+ /* PEM otherwise */
+ } else {
+ int pem;
+
+ /* PEM number is equal to domain */
+ pem = pci_get_domain(pci_dev);
+
+ /* Hardcode appropriate PEM numbers */
+ if (pem < 3 )
+ return ((0x1 << PCI_RID_DOMAIN_SHIFT) | bsf);
+
+ if (pem < 6 )
+ return ((0x3 << PCI_RID_DOMAIN_SHIFT) | bsf);
+
+ if (pem < 9 )
+ return ((0x9 << PCI_RID_DOMAIN_SHIFT) | bsf);
+
+ if (pem < 12 )
+ return ((0xB << PCI_RID_DOMAIN_SHIFT) | bsf);
+ }
+
+ return (0);
+}
+
+static __inline uint32_t
+its_get_devid_default(device_t pci_dev)
+{
+
+ return (PCI_DEVID_GENERIC(pci_dev));
+}
+
+static uint32_t
+its_get_devid(device_t pci_dev)
+{
+ struct its_quirks *quirk = &its_quirks[0];
+
+ while (quirk->cpuid != 0) {
+ if (CPU_MATCH_RAW(quirk->cpuid_mask, quirk->cpuid)) {
+ if (quirk->devid_func != NULL)
+ return ((*quirk->devid_func)(pci_dev));
+ }
+ quirk++;
+ }
+
+ return (its_get_devid_default(pci_dev));
+}
+
static int
gic_v3_its_attach(device_t dev)
{
@@ -1300,7 +1385,7 @@
if (newdev != NULL)
return (newdev);
- devid = PCI_DEVID(pci_dev);
+ devid = its_get_devid(pci_dev);
/* There was no previously created device. Create one now */
newdev = malloc(sizeof(*newdev), M_GIC_V3_ITS, (M_WAITOK | M_ZERO));
Index: sys/arm64/arm64/gic_v3_var.h
===================================================================
--- sys/arm64/arm64/gic_v3_var.h
+++ sys/arm64/arm64/gic_v3_var.h
@@ -277,13 +277,14 @@
reg, val); \
})
-#define PCI_DEVID(pci_dev) \
+#define PCI_RID_DOMAIN_SHIFT 16
+
+#define PCI_DEVID_GENERIC(pci_dev) \
({ \
- (((pci_get_domain(pci_dev) >> 2) << 19) | \
- ((pci_get_domain(pci_dev) % 4) << 16) | \
- (pci_get_bus(pci_dev) << 8) | \
- (pci_get_slot(pci_dev) << 3) | \
- (pci_get_function(pci_dev) << 0)); \
+ ((pci_get_domain(pci_dev) << PCI_RID_DOMAIN_SHIFT) | \
+ (pci_get_bus(pci_dev) << PCI_RID_BUS_SHIFT) | \
+ (pci_get_slot(pci_dev) << PCI_RID_SLOT_SHIFT) | \
+ (pci_get_function(pci_dev) << PCI_RID_FUNC_SHIFT)); \
})
/*

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 8:18 PM (3 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31795747
Default Alt Text
D3118.id7045.diff (4 KB)

Event Timeline