Index: sys/arm64/arm64/gic_v3_its.c =================================================================== --- sys/arm64/arm64/gic_v3_its.c +++ sys/arm64/arm64/gic_v3_its.c @@ -101,6 +101,8 @@ 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_get_devbits(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 *); @@ -142,6 +144,7 @@ */ /* Cavium ThunderX PCI devid acquire function */ +static uint32_t its_get_devbits_thunder(device_t); static uint32_t its_get_devid_thunder(device_t); static const struct its_quirks its_quirks[] = { @@ -149,6 +152,7 @@ .cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0), .cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK, .devid_func = its_get_devid_thunder, + .devbits_func = its_get_devbits_thunder, }, }; @@ -299,7 +303,6 @@ { uint64_t gits_baser, gits_tmp; uint64_t type, esize, cache, share, psz; - uint64_t gits_typer; size_t page_size, npages, nitspages, nidents, tn; size_t its_tbl_size; vm_offset_t ptab_vaddr; @@ -308,9 +311,6 @@ page_size = PAGE_SIZE_64K; - /* Read features first */ - gits_typer = gic_its_read(sc, 8, GITS_TYPER); - for (tn = 0; tn < GITS_BASER_NUM; tn++) { gits_baser = gic_its_read(sc, 8, GITS_BASER(tn)); type = GITS_BASER_TYPE(gits_baser); @@ -324,7 +324,7 @@ case GITS_BASER_TYPE_RES7: continue; case GITS_BASER_TYPE_DEV: - nidents = (1 << GITS_TYPER_DEVB(gits_typer)); + nidents = (1 << its_get_devbits(sc->dev)); its_tbl_size = esize * nidents; its_tbl_size = roundup2(its_tbl_size, page_size); npages = howmany(its_tbl_size, PAGE_SIZE); @@ -1447,6 +1447,45 @@ return (0); } +static uint32_t +its_get_devbits_thunder(device_t dev) +{ + device_printf(dev, "QUIRK: hardcoding 20MB for ITS table size\n"); + + /* Hardcode DEVB to 20MB, 13 bits */ + return (13); +} + +static __inline uint32_t +its_get_devbits_default(device_t dev) +{ + uint64_t gits_typer; + struct gic_v3_its_softc *sc; + + sc = device_get_softc(dev); + + gits_typer = gic_its_read(sc, 8, GITS_TYPER); + + return (GITS_TYPER_DEVB(gits_typer)); +} + +static uint32_t +its_get_devbits(device_t dev) +{ + const struct its_quirks *quirk; + size_t i; + + for (i = 0; i < nitems(its_quirks); i++) { + quirk = &its_quirks[i]; + if (CPU_MATCH_RAW(quirk->cpuid_mask, quirk->cpuid)) { + if (quirk->devbits_func != NULL) + return ((*quirk->devbits_func)(dev)); + } + } + + return (its_get_devbits_default(dev)); +} + static __inline uint32_t its_get_devid_default(device_t pci_dev) { Index: sys/arm64/arm64/gic_v3_var.h =================================================================== --- sys/arm64/arm64/gic_v3_var.h +++ sys/arm64/arm64/gic_v3_var.h @@ -235,12 +235,14 @@ }; /* Stuff that is specific to the vendor's implementation */ +typedef uint32_t (*its_devbits_func_t)(device_t); typedef uint32_t (*its_devid_func_t)(device_t); struct its_quirks { uint64_t cpuid; uint64_t cpuid_mask; its_devid_func_t devid_func; + its_devbits_func_t devbits_func; }; extern devclass_t gic_v3_its_devclass;