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