Module Name: src Committed By: jmcneill Date: Sun Jun 30 17:33:59 UTC 2019
Modified Files: src/sys/arch/arm/cortex: gicv3_its.c Log Message: Cleanup ThunderX quirk and print cache / shareability details for ITT tables To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/cortex/gicv3_its.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/cortex/gicv3_its.c diff -u src/sys/arch/arm/cortex/gicv3_its.c:1.20 src/sys/arch/arm/cortex/gicv3_its.c:1.21 --- src/sys/arch/arm/cortex/gicv3_its.c:1.20 Sun Jun 30 10:10:19 2019 +++ src/sys/arch/arm/cortex/gicv3_its.c Sun Jun 30 17:33:59 2019 @@ -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, */ #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) @@ -617,34 +639,36 @@ gicv3_its_command_init(struct gicv3_soft } static void -gicv3_its_table_init(struct gicv3_softc *sc, struct gicv3_its *its) +gicv3_its_table_params(struct gicv3_softc *sc, struct gicv3_its *its, + u_int *devbits, u_int *innercache, u_int *share) { - u_int table_size, page_size, table_align; - uint64_t baser; - int tab; const uint64_t typer = gits_read_8(its, GITS_TYPER); + const uint32_t iidr = gits_read_4(its, GITS_IIDR); - /* 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; + /* 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; + + 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 * 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 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 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)]); } }