Index: head/sys/dev/bhnd/bcma/bcma_erom.c =================================================================== --- head/sys/dev/bhnd/bcma/bcma_erom.c +++ head/sys/dev/bhnd/bcma/bcma_erom.c @@ -1367,6 +1367,157 @@ 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 @@ 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 }; Index: head/sys/dev/bhnd/bhnd_erom.h =================================================================== --- head/sys/dev/bhnd/bhnd_erom.h +++ head/sys/dev/bhnd/bhnd_erom.h @@ -240,4 +240,19 @@ 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_ */ Index: head/sys/dev/bhnd/bhnd_erom_if.m =================================================================== --- head/sys/dev/bhnd/bhnd_erom_if.m +++ head/sys/dev/bhnd/bhnd_erom_if.m @@ -241,3 +241,16 @@ 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; +}; Index: head/sys/dev/bhnd/siba/siba_erom.c =================================================================== --- head/sys/dev/bhnd/siba/siba_erom.c +++ head/sys/dev/bhnd/siba/siba_erom.c @@ -519,6 +519,65 @@ 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 @@ 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 }; Index: head/sys/mips/broadcom/bcm_machdep.c =================================================================== --- head/sys/mips/broadcom/bcm_machdep.c +++ head/sys/mips/broadcom/bcm_machdep.c @@ -343,6 +343,9 @@ 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);