Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/gic_v3_its.c
Show First 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
static void its_cmd_mapc(struct gic_v3_its_softc *, struct its_col *, uint8_t); | static void its_cmd_mapc(struct gic_v3_its_softc *, struct its_col *, uint8_t); | ||||
static void its_cmd_mapvi(struct gic_v3_its_softc *, struct its_dev *, uint32_t, | static void its_cmd_mapvi(struct gic_v3_its_softc *, struct its_dev *, uint32_t, | ||||
uint32_t); | uint32_t); | ||||
static void its_cmd_mapi(struct gic_v3_its_softc *, struct its_dev *, uint32_t); | 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_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 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_init_conftable(struct gic_v3_its_softc *); | ||||
static void lpi_bitmap_init(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 void lpi_init_cpu(struct gic_v3_its_softc *); | ||||
static int lpi_config_cpu(struct gic_v3_its_softc *); | static int lpi_config_cpu(struct gic_v3_its_softc *); | ||||
const char *its_ptab_cache[] = { | const char *its_ptab_cache[] = { | ||||
[GITS_BASER_CACHE_NCNB] = "(NC,NB)", | [GITS_BASER_CACHE_NCNB] = "(NC,NB)", | ||||
[GITS_BASER_CACHE_NC] = "(NC)", | [GITS_BASER_CACHE_NC] = "(NC)", | ||||
Show All 25 Lines | |||||
/* | /* | ||||
* Vendor specific quirks. | * Vendor specific quirks. | ||||
* One needs to add appropriate entry to its_quirks[] | * One needs to add appropriate entry to its_quirks[] | ||||
* table if the imlementation varies from the generic ARM ITS. | * table if the imlementation varies from the generic ARM ITS. | ||||
*/ | */ | ||||
/* Cavium ThunderX PCI devid acquire function */ | /* 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 uint32_t its_get_devid_thunder(device_t); | ||||
static const struct its_quirks its_quirks[] = { | static const struct its_quirks its_quirks[] = { | ||||
{ | { | ||||
/* | |||||
* Hardware: Cavium ThunderX | |||||
* Chip revision: Pass 1.0, Pass 1.1 | |||||
*/ | |||||
.cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0), | .cpuid = CPU_ID_RAW(CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0), | ||||
.cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK, | .cpuid_mask = CPU_IMPL_MASK | CPU_PART_MASK, | ||||
.devid_func = its_get_devid_thunder, | .devid_func = its_get_devid_thunder, | ||||
.devbits_func = its_get_devbits_thunder, | |||||
}, | }, | ||||
}; | }; | ||||
static struct gic_v3_its_softc *its_sc; | static struct gic_v3_its_softc *its_sc; | ||||
#define gic_its_read(sc, len, reg) \ | #define gic_its_read(sc, len, reg) \ | ||||
bus_read_##len(&sc->its_res[0], reg) | bus_read_##len(&sc->its_res[0], reg) | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | gic_v3_its_detach(device_t dev) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
its_alloc_tables(struct gic_v3_its_softc *sc) | its_alloc_tables(struct gic_v3_its_softc *sc) | ||||
{ | { | ||||
uint64_t gits_baser, gits_tmp; | uint64_t gits_baser, gits_tmp; | ||||
uint64_t type, esize, cache, share, psz; | uint64_t type, esize, cache, share, psz; | ||||
uint64_t gits_typer; | |||||
size_t page_size, npages, nitspages, nidents, tn; | size_t page_size, npages, nitspages, nidents, tn; | ||||
size_t its_tbl_size; | size_t its_tbl_size; | ||||
vm_offset_t ptab_vaddr; | vm_offset_t ptab_vaddr; | ||||
vm_paddr_t ptab_paddr; | vm_paddr_t ptab_paddr; | ||||
boolean_t first = TRUE; | boolean_t first = TRUE; | ||||
page_size = PAGE_SIZE_64K; | 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++) { | for (tn = 0; tn < GITS_BASER_NUM; tn++) { | ||||
gits_baser = gic_its_read(sc, 8, GITS_BASER(tn)); | gits_baser = gic_its_read(sc, 8, GITS_BASER(tn)); | ||||
type = GITS_BASER_TYPE(gits_baser); | type = GITS_BASER_TYPE(gits_baser); | ||||
/* Get the Table Entry size */ | /* Get the Table Entry size */ | ||||
esize = GITS_BASER_ESIZE(gits_baser); | esize = GITS_BASER_ESIZE(gits_baser); | ||||
switch (type) { | switch (type) { | ||||
case GITS_BASER_TYPE_UNIMPL: /* fall through */ | case GITS_BASER_TYPE_UNIMPL: /* fall through */ | ||||
case GITS_BASER_TYPE_RES5: | case GITS_BASER_TYPE_RES5: | ||||
case GITS_BASER_TYPE_RES6: | case GITS_BASER_TYPE_RES6: | ||||
case GITS_BASER_TYPE_RES7: | case GITS_BASER_TYPE_RES7: | ||||
continue; | continue; | ||||
case GITS_BASER_TYPE_DEV: | 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 = esize * nidents; | ||||
its_tbl_size = roundup2(its_tbl_size, page_size); | its_tbl_size = roundup2(its_tbl_size, page_size); | ||||
npages = howmany(its_tbl_size, PAGE_SIZE); | npages = howmany(its_tbl_size, PAGE_SIZE); | ||||
break; | break; | ||||
default: | default: | ||||
npages = howmany(page_size, PAGE_SIZE); | npages = howmany(page_size, PAGE_SIZE); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,104 Lines • ▼ Show 20 Lines | /* PEM otherwise */ | ||||
if (pem < 9) | if (pem < 9) | ||||
return ((0x9 << PCI_RID_DOMAIN_SHIFT) | bsf); | return ((0x9 << PCI_RID_DOMAIN_SHIFT) | bsf); | ||||
if (pem < 12) | if (pem < 12) | ||||
return ((0xB << PCI_RID_DOMAIN_SHIFT) | bsf); | return ((0xB << PCI_RID_DOMAIN_SHIFT) | bsf); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | |||||
static uint32_t | |||||
its_get_devbits_thunder(device_t dev) | |||||
{ | |||||
uint32_t devid_bits; | |||||
/* | |||||
* GITS_TYPER[17:13] of ThunderX reports that device IDs | |||||
* are to be 21 bits in length. | |||||
* The entry size of the ITS table can be read from GITS_BASERn[52:48] | |||||
* and on ThunderX is supposed to be 8 bytes in length (for device | |||||
* table). Finally the page size that is to be used by ITS to access | |||||
* this table will be set to 64KB. | |||||
* | |||||
* This gives 0x200000 entries of size 0x8 bytes covered by 256 pages | |||||
* each of which 64KB in size. The number of pages (minus 1) should | |||||
* then be written to GITS_BASERn[7:0]. In that case this value would | |||||
* be 0xFF but on ThunderX the maximum value that HW accepts is 0xFD. | |||||
* | |||||
* Set arbitrary number of device ID bits to 20 in order to limit | |||||
* the number of entries in ITS device table to 0x100000 and hence | |||||
* the table size to 8MB. | |||||
*/ | |||||
devid_bits = 20; | |||||
if (bootverbose) { | |||||
device_printf(dev, | |||||
"Limiting number of Device ID bits implemented to %d\n", | |||||
devid_bits); | |||||
} | |||||
return (devid_bits); | |||||
} | |||||
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 | static __inline uint32_t | ||||
its_get_devid_default(device_t pci_dev) | its_get_devid_default(device_t pci_dev) | ||||
{ | { | ||||
return (PCI_DEVID_GENERIC(pci_dev)); | return (PCI_DEVID_GENERIC(pci_dev)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 111 Lines • Show Last 20 Lines |