From af57b7fff7723cbe9c68bc4a8c58fbcb62b4f689 Mon Sep 17 00:00:00 2001 From: jmcneill Date: Sun, 30 Jun 2019 17:33:59 +0000 Subject: [PATCH] Cleanup ThunderX quirk and print cache / shareability details for ITT tables --- sys/arch/arm/cortex/gicv3_its.c | 81 +++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/sys/arch/arm/cortex/gicv3_its.c b/sys/arch/arm/cortex/gicv3_its.c index 8971fbbacce3..e3ec2710c2c1 100644 --- a/sys/arch/arm/cortex/gicv3_its.c +++ b/sys/arch/arm/cortex/gicv3_its.c @@ -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 -__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 #include @@ -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)]); } }