svn commit: r317380 - in head/sys: dev/bhnd dev/bhnd/bcma dev/bhnd/siba mips/broadcom
Landon J. Fuller
landonf at FreeBSD.org
Mon Apr 24 18:35:27 UTC 2017
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);
More information about the svn-src-head
mailing list