Date: Mon, 24 Apr 2017 18:35:25 +0000 (UTC) From: "Landon J. Fuller" <landonf@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317380 - in head/sys: dev/bhnd dev/bhnd/bcma dev/bhnd/siba mips/broadcom Message-ID: <201704241835.v3OIZPAu013895@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: landonf Date: Mon Apr 24 18:35:25 2017 New Revision: 317380 URL: https://svnweb.freebsd.org/changeset/base/317380 Log: Add support for dumping bcma/siba EROM tables to the console via a new BHND_EROM_DUMP() method. Dump the EROM tables to the coneole on mips/broadcom devices if bootverbose is enabled; this functionality is primarily useful when debugging SoC EROM parsing and device matching issues during early boot. Reviewed by: mizhka Approved by: adrian (mentor) Sponsored by: Plausible Labs Differential Revision: https://reviews.freebsd.org/D10122 Modified: head/sys/dev/bhnd/bcma/bcma_erom.c head/sys/dev/bhnd/bhnd_erom.h head/sys/dev/bhnd/bhnd_erom_if.m head/sys/dev/bhnd/siba/siba_erom.c head/sys/mips/broadcom/bcm_machdep.c Modified: head/sys/dev/bhnd/bcma/bcma_erom.c ============================================================================== --- head/sys/dev/bhnd/bcma/bcma_erom.c Mon Apr 24 18:09:52 2017 (r317379) +++ head/sys/dev/bhnd/bcma/bcma_erom.c Mon Apr 24 18:35:25 2017 (r317380) @@ -1367,6 +1367,157 @@ failed: return error; } +static int +bcma_erom_dump(bhnd_erom_t *erom) +{ + struct bcma_erom *sc; + uint32_t entry; + int error; + + sc = (struct bcma_erom *)erom; + + bcma_erom_reset(sc); + + while (!(error = bcma_erom_read32(sc, &entry))) { + /* Handle EOF */ + if (entry == BCMA_EROM_TABLE_EOF) { + EROM_LOG(sc, "EOF\n"); + return (0); + } + + /* Invalid entry */ + if (!BCMA_EROM_GET_ATTR(entry, ENTRY_ISVALID)) { + EROM_LOG(sc, "invalid EROM entry %#x\n", entry); + return (EINVAL); + } + + switch (BCMA_EROM_GET_ATTR(entry, ENTRY_TYPE)) { + case BCMA_EROM_ENTRY_TYPE_CORE: { + /* CoreDescA */ + EROM_LOG(sc, "coreA (0x%x)\n", entry); + EROM_LOG(sc, "\tdesigner:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREA_DESIGNER)); + EROM_LOG(sc, "\tid:\t\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREA_ID)); + EROM_LOG(sc, "\tclass:\t\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREA_CLASS)); + + /* CoreDescB */ + if ((error = bcma_erom_read32(sc, &entry))) { + EROM_LOG(sc, "error reading CoreDescB: %d\n", + error); + return (error); + } + + if (!BCMA_EROM_ENTRY_IS(entry, CORE)) { + EROM_LOG(sc, "invalid core descriptor; found " + "unexpected entry %#x (type=%s)\n", + entry, bcma_erom_entry_type_name(entry)); + return (EINVAL); + } + + EROM_LOG(sc, "coreB (0x%x)\n", entry); + EROM_LOG(sc, "\trev:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREB_REV)); + EROM_LOG(sc, "\tnummp:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREB_NUM_MP)); + EROM_LOG(sc, "\tnumdp:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREB_NUM_DP)); + EROM_LOG(sc, "\tnumwmp:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREB_NUM_WMP)); + EROM_LOG(sc, "\tnumwsp:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, COREB_NUM_WMP)); + + break; + } + case BCMA_EROM_ENTRY_TYPE_MPORT: + EROM_LOG(sc, "\tmport 0x%x\n", entry); + EROM_LOG(sc, "\t\tport:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, MPORT_NUM)); + EROM_LOG(sc, "\t\tid:\t\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, MPORT_ID)); + break; + + case BCMA_EROM_ENTRY_TYPE_REGION: { + bool addr64; + uint8_t size_type; + + addr64 = (BCMA_EROM_GET_ATTR(entry, REGION_64BIT) != 0); + size_type = BCMA_EROM_GET_ATTR(entry, REGION_SIZE); + + EROM_LOG(sc, "\tregion 0x%x:\n", entry); + EROM_LOG(sc, "\t\t%s:\t0x%x\n", + addr64 ? "baselo" : "base", + BCMA_EROM_GET_ATTR(entry, REGION_BASE)); + EROM_LOG(sc, "\t\tport:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, REGION_PORT)); + EROM_LOG(sc, "\t\ttype:\t0x%x\n", + BCMA_EROM_GET_ATTR(entry, REGION_TYPE)); + EROM_LOG(sc, "\t\tsztype:\t0x%hhx\n", size_type); + + /* Read the base address high bits */ + if (addr64) { + if ((error = bcma_erom_read32(sc, &entry))) { + EROM_LOG(sc, "error reading region " + "base address high bits %d\n", + error); + return (error); + } + + EROM_LOG(sc, "\t\tbasehi:\t0x%x\n", entry); + } + + /* Read extended size descriptor */ + if (size_type == BCMA_EROM_REGION_SIZE_OTHER) { + bool size64; + + if ((error = bcma_erom_read32(sc, &entry))) { + EROM_LOG(sc, "error reading region " + "size descriptor %d\n", + error); + return (error); + } + + if (BCMA_EROM_GET_ATTR(entry, RSIZE_64BIT)) + size64 = true; + else + size64 = false; + + EROM_LOG(sc, "\t\t%s:\t0x%x\n", + size64 ? "sizelo" : "size", + BCMA_EROM_GET_ATTR(entry, RSIZE_VAL)); + + if (size64) { + error = bcma_erom_read32(sc, &entry); + if (error) { + EROM_LOG(sc, "error reading " + "region size high bits: " + "%d\n", error); + return (error); + } + + EROM_LOG(sc, "\t\tsizehi:\t0x%x\n", + entry); + } + } + break; + } + + default: + EROM_LOG(sc, "unknown EROM entry 0x%x (type=%s)\n", + entry, bcma_erom_entry_type_name(entry)); + return (EINVAL); + } + } + + if (error == ENOENT) + EROM_LOG(sc, "BCMA EROM table missing terminating EOF\n"); + else if (error) + EROM_LOG(sc, "EROM read failed: %d\n", error); + + return (error); +} + static kobj_method_t bcma_erom_methods[] = { KOBJMETHOD(bhnd_erom_probe, bcma_erom_probe), KOBJMETHOD(bhnd_erom_probe_static, bcma_erom_probe_static), @@ -1377,6 +1528,7 @@ static kobj_method_t bcma_erom_methods[] KOBJMETHOD(bhnd_erom_free_core_table, bcma_erom_free_core_table), KOBJMETHOD(bhnd_erom_lookup_core, bcma_erom_lookup_core), KOBJMETHOD(bhnd_erom_lookup_core_addr, bcma_erom_lookup_core_addr), + KOBJMETHOD(bhnd_erom_dump, bcma_erom_dump), KOBJMETHOD_END }; Modified: head/sys/dev/bhnd/bhnd_erom.h ============================================================================== --- head/sys/dev/bhnd/bhnd_erom.h Mon Apr 24 18:09:52 2017 (r317379) +++ head/sys/dev/bhnd/bhnd_erom.h Mon Apr 24 18:35:25 2017 (r317380) @@ -240,4 +240,19 @@ bhnd_erom_lookup_core_addr(bhnd_erom_t * core, addr, size)); }; +/** + * Enumerate and print all entries in @p erom. + * + * @param erom The erom parser to be enumerated. + * + * @retval 0 success + * @retval non-zero If an error occurs parsing the EROM table, a regular + * unix error code will be returned. + */ +static inline int +bhnd_erom_dump(bhnd_erom_t *erom) +{ + return (BHND_EROM_DUMP(erom)); +} + #endif /* _BHND_EROM_BHND_EROM_H_ */ Modified: head/sys/dev/bhnd/bhnd_erom_if.m ============================================================================== --- head/sys/dev/bhnd/bhnd_erom_if.m Mon Apr 24 18:09:52 2017 (r317379) +++ head/sys/dev/bhnd/bhnd_erom_if.m Mon Apr 24 18:35:25 2017 (r317380) @@ -241,3 +241,16 @@ METHOD int lookup_core_addr { bhnd_addr_t *addr; bhnd_size_t *size; }; + +/** + * Enumerate and print all EROM table entries. + * + * @param erom The erom parser to be enumerated. + * + * @retval 0 success + * @retval non-zero If an error occurs reading the EROM table, a regular + * unix error code will be returned. + */ +METHOD int dump { + bhnd_erom_t *erom; +}; Modified: head/sys/dev/bhnd/siba/siba_erom.c ============================================================================== --- head/sys/dev/bhnd/siba/siba_erom.c Mon Apr 24 18:09:52 2017 (r317379) +++ head/sys/dev/bhnd/siba/siba_erom.c Mon Apr 24 18:35:25 2017 (r317380) @@ -519,6 +519,65 @@ siba_erom_free_core_table(bhnd_erom_t *e free(cores, M_BHND); } +/* BHND_EROM_DUMP() */ +static int +siba_erom_dump(bhnd_erom_t *erom) +{ + struct siba_erom *sc; + int error; + + sc = (struct siba_erom *)erom; + + /* Enumerate all cores. */ + for (u_int i = 0; i < sc->io.ncores; i++) { + uint32_t idhigh, idlow; + uint32_t nraddr; + + idhigh = siba_eio_read_4(&sc->io, i, + SB0_REG_ABS(SIBA_CFG0_IDHIGH)); + idlow = siba_eio_read_4(&sc->io, i, + SB0_REG_ABS(SIBA_CFG0_IDLOW)); + + printf("siba core %u:\n", i); + printf("\tvendor:\t0x%04x\n", SIBA_REG_GET(idhigh, IDH_VENDOR)); + printf("\tdevice:\t0x%04x\n", SIBA_REG_GET(idhigh, IDH_DEVICE)); + printf("\trev:\t0x%04x\n", SIBA_IDH_CORE_REV(idhigh)); + printf("\tsbrev:\t0x%02x\n", SIBA_REG_GET(idlow, IDL_SBREV)); + + /* Enumerate the address match registers */ + nraddr = SIBA_REG_GET(idlow, IDL_NRADDR); + printf("\tnraddr\t0x%04x\n", nraddr); + + for (size_t addrspace = 0; addrspace < nraddr; addrspace++) { + uint32_t am, am_addr, am_size; + u_int am_offset; + + /* Determine the register offset */ + am_offset = siba_admatch_offset(addrspace); + if (am_offset == 0) { + printf("addrspace %zu unsupported", + addrspace); + break; + } + + /* Read and parse the address match register */ + am = siba_eio_read_4(&sc->io, i, am_offset); + error = siba_parse_admatch(am, &am_addr, &am_size); + if (error) { + printf("failed to decode address match " + "register value 0x%x\n", am); + continue; + } + + printf("\taddrspace %zu\n", addrspace); + printf("\t\taddr: 0x%08x\n", am_addr); + printf("\t\tsize: 0x%08x\n", am_size); + } + } + + return (0); +} + static kobj_method_t siba_erom_methods[] = { KOBJMETHOD(bhnd_erom_probe, siba_erom_probe), KOBJMETHOD(bhnd_erom_probe_static, siba_erom_probe_static), @@ -529,6 +588,7 @@ static kobj_method_t siba_erom_methods[] KOBJMETHOD(bhnd_erom_free_core_table, siba_erom_free_core_table), KOBJMETHOD(bhnd_erom_lookup_core, siba_erom_lookup_core), KOBJMETHOD(bhnd_erom_lookup_core_addr, siba_erom_lookup_core_addr), + KOBJMETHOD(bhnd_erom_dump, siba_erom_dump), KOBJMETHOD_END }; Modified: head/sys/mips/broadcom/bcm_machdep.c ============================================================================== --- head/sys/mips/broadcom/bcm_machdep.c Mon Apr 24 18:09:52 2017 (r317379) +++ head/sys/mips/broadcom/bcm_machdep.c Mon Apr 24 18:35:25 2017 (r317380) @@ -343,6 +343,9 @@ bcm_init_platform_data(struct bcm_platfo return (error); } + if (bootverbose) + bhnd_erom_dump(&bp->erom.obj); + /* Fetch chipcommon core info */ error = bcm_find_core(bp, bcm_chipc_cores, nitems(bcm_chipc_cores), &bp->cc_id, &bp->cc_addr);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704241835.v3OIZPAu013895>