Cleanup ThunderX quirk and print cache / shareability details for ITT tables
This commit is contained in:
parent
180fc3b4ec
commit
af57b7fff7
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: gicv3_its.c,v 1.20 2019/06/30 10:10:19 jmcneill Exp $ */
|
||||
/* $NetBSD: gicv3_its.c,v 1.21 2019/06/30 17:33:59 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2018 The NetBSD Foundation, Inc.
|
||||
@ -32,7 +32,7 @@
|
||||
#define _INTR_PRIVATE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.20 2019/06/30 10:10:19 jmcneill Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.21 2019/06/30 17:33:59 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kmem.h>
|
||||
@ -61,7 +61,29 @@ __KERNEL_RCSID(0, "$NetBSD: gicv3_its.c,v 1.20 2019/06/30 10:10:19 jmcneill Exp
|
||||
*/
|
||||
#define GITS_IIDR_PID_CAVIUM_THUNDERX 0xa1
|
||||
#define GITS_IIDR_IMP_CAVIUM 0x34c
|
||||
#define GITS_IIDR_CAVIUM_ERRATA_MASK (GITS_IIDR_Implementor|GITS_IIDR_ProductID|GITS_IIDR_Variant)
|
||||
#define GITS_IIDR_CAVIUM_ERRATA_VALUE \
|
||||
(__SHIFTIN(GITS_IIDR_IMP_CAVIUM, GITS_IIDR_Implementor) | \
|
||||
__SHIFTIN(GITS_IIDR_PID_CAVIUM_THUNDERX, GITS_IIDR_ProductID) | \
|
||||
__SHIFTIN(0, GITS_IIDR_Variant))
|
||||
|
||||
static const char * gits_cache_type[] = {
|
||||
[GITS_Cache_DEVICE_nGnRnE] = "Device-nGnRnE",
|
||||
[GITS_Cache_NORMAL_NC] = "Non-cacheable",
|
||||
[GITS_Cache_NORMAL_RA_WT] = "Cacheable RA WT",
|
||||
[GITS_Cache_NORMAL_RA_WB] = "Cacheable RA WB",
|
||||
[GITS_Cache_NORMAL_WA_WT] = "Cacheable WA WT",
|
||||
[GITS_Cache_NORMAL_WA_WB] = "Cacheable WA WB",
|
||||
[GITS_Cache_NORMAL_RA_WA_WT] = "Cacheable RA WA WT",
|
||||
[GITS_Cache_NORMAL_RA_WA_WB] = "Cacheable RA WA WB",
|
||||
};
|
||||
|
||||
static const char * gits_share_type[] = {
|
||||
[GITS_Shareability_NS] = "Non-shareable",
|
||||
[GITS_Shareability_IS] = "Inner shareable",
|
||||
[GITS_Shareability_OS] = "Outer shareable",
|
||||
[3] = "(Reserved)",
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
gits_read_4(struct gicv3_its *its, bus_size_t reg)
|
||||
@ -616,35 +638,37 @@ gicv3_its_command_init(struct gicv3_softc *sc, struct gicv3_its *its)
|
||||
gits_write_8(its, GITS_CWRITER, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gicv3_its_table_params(struct gicv3_softc *sc, struct gicv3_its *its,
|
||||
u_int *devbits, u_int *innercache, u_int *share)
|
||||
{
|
||||
|
||||
const uint64_t typer = gits_read_8(its, GITS_TYPER);
|
||||
const uint32_t iidr = gits_read_4(its, GITS_IIDR);
|
||||
|
||||
/* Default values */
|
||||
*devbits = __SHIFTOUT(typer, GITS_TYPER_Devbits) + 1;
|
||||
*innercache = GITS_Cache_NORMAL_WA_WB;
|
||||
*share = GITS_Shareability_IS;
|
||||
|
||||
/* Cavium ThunderX errata */
|
||||
if ((iidr & GITS_IIDR_CAVIUM_ERRATA_MASK) == GITS_IIDR_CAVIUM_ERRATA_VALUE) {
|
||||
*devbits = 20; /* 8Mb */
|
||||
*innercache = GITS_Cache_DEVICE_nGnRnE;
|
||||
aprint_normal_dev(sc->sc_dev, "Cavium ThunderX errata detected\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its)
|
||||
{
|
||||
u_int table_size, page_size, table_align;
|
||||
u_int devbits, innercache, share;
|
||||
const char *table_type;
|
||||
uint64_t baser;
|
||||
int tab;
|
||||
|
||||
const uint64_t typer = gits_read_8(its, GITS_TYPER);
|
||||
|
||||
/* devbits and innercache defaults */
|
||||
u_int devbits = __SHIFTOUT(typer, GITS_TYPER_Devbits) + 1;
|
||||
u_int innercache = GITS_Cache_NORMAL_WA_WB;
|
||||
u_int share = GITS_Shareability_IS;
|
||||
|
||||
uint32_t iidr = gits_read_4(its, GITS_IIDR);
|
||||
const uint32_t ctx =
|
||||
__SHIFTIN(GITS_IIDR_IMP_CAVIUM, GITS_IIDR_Implementor) |
|
||||
__SHIFTIN(GITS_IIDR_PID_CAVIUM_THUNDERX, GITS_IIDR_ProductID) |
|
||||
__SHIFTIN(0, GITS_IIDR_Variant);
|
||||
const uint32_t mask =
|
||||
GITS_IIDR_Implementor |
|
||||
GITS_IIDR_ProductID |
|
||||
GITS_IIDR_Variant;
|
||||
|
||||
if ((iidr & mask) == ctx) {
|
||||
devbits = 20; /* 8Mb */
|
||||
innercache = GITS_Cache_DEVICE_nGnRnE;
|
||||
aprint_normal_dev(sc->sc_dev, "Cavium ThunderX errata detected\n");
|
||||
}
|
||||
gicv3_its_table_params(sc, its, &devbits, &innercache, &share);
|
||||
|
||||
for (tab = 0; tab < 8; tab++) {
|
||||
baser = gits_read_8(its, GITS_BASERn(tab));
|
||||
@ -673,12 +697,14 @@ gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its)
|
||||
* Table size scales with the width of the DeviceID.
|
||||
*/
|
||||
table_size = roundup(entry_size * (1 << devbits), page_size);
|
||||
table_type = "Devices";
|
||||
break;
|
||||
case GITS_Type_InterruptCollections:
|
||||
/*
|
||||
* Allocate space for one interrupt collection per CPU.
|
||||
*/
|
||||
table_size = roundup(entry_size * MAXCPUS, page_size);
|
||||
table_type = "Collections";
|
||||
break;
|
||||
default:
|
||||
table_size = 0;
|
||||
@ -688,7 +714,6 @@ gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its)
|
||||
if (table_size == 0)
|
||||
continue;
|
||||
|
||||
aprint_normal_dev(sc->sc_dev, "ITS TT%u type %#x size %#x\n", tab, (u_int)__SHIFTOUT(baser, GITS_BASER_Type), table_size);
|
||||
gicv3_dma_alloc(sc, &its->its_tab[tab], table_size, table_align);
|
||||
|
||||
baser &= ~GITS_BASER_Size;
|
||||
@ -710,6 +735,12 @@ gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its)
|
||||
|
||||
gits_write_8(its, GITS_BASERn(tab), baser);
|
||||
}
|
||||
|
||||
baser = gits_read_8(its, GITS_BASERn(tab));
|
||||
aprint_normal_dev(sc->sc_dev, "ITS [#%d] %s table @ %#lx/%#x, %s, %s\n",
|
||||
tab, table_type, its->its_tab[tab].segs[0].ds_addr, table_size,
|
||||
gits_cache_type[__SHIFTOUT(baser, GITS_BASER_InnerCache)],
|
||||
gits_share_type[__SHIFTOUT(baser, GITS_BASER_Shareability)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user