svn commit: r331744 - in head: share/man/man9 sys/dev/bhnd sys/dev/bhnd/bcma sys/dev/bhnd/bhndb sys/dev/bhnd/siba

Landon J. Fuller landonf at FreeBSD.org
Thu Mar 29 19:44:17 UTC 2018


Author: landonf
Date: Thu Mar 29 19:44:15 2018
New Revision: 331744
URL: https://svnweb.freebsd.org/changeset/base/331744

Log:
  bhnd(4): include a subset of the ChipCommon capability flags in bhnd_chipid;
  this provides early access to device capability flags required by bhnd(4)
  bus and bhndb(4) bridge drivers.

Modified:
  head/share/man/man9/bhnd.9
  head/sys/dev/bhnd/bcma/bcma_erom.c
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_erom.c
  head/sys/dev/bhnd/bhnd_erom.h
  head/sys/dev/bhnd/bhnd_eromvar.h
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/bhndb/bhndb_pci.c
  head/sys/dev/bhnd/siba/siba_erom.c

Modified: head/share/man/man9/bhnd.9
==============================================================================
--- head/share/man/man9/bhnd.9	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/share/man/man9/bhnd.9	Thu Mar 29 19:44:15 2018	(r331744)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 19, 2018
+.Dd March 26, 2018
 .Dt BHND 9
 .Os
 .Sh NAME
@@ -1130,6 +1130,10 @@ chip, each of which may require driver workarounds for
 unpopulated components, etc.
 .It Fa chip_type
 The interconnect architecture used by this chip.
+.It Fa chip_caps
+The
+.Nm
+capability flags supported by this chip.
 .It Fa enum_addr
 The backplane enumeration address.
 On SSB devices, this will be the base address of the first SSB core.
@@ -1154,6 +1158,16 @@ This BCMA-derived interconnect is found in Broadcom BC
 BCM63xx xDSL SoCs.
 UBUS is not currently supported by
 .Xr bhnd 4 .
+.El
+.Pp
+The following
+.Fa chip_caps
+flags are supported:
+.Bl -tag -width ".Dv BHND_CAP_BP64" -offset indent -compact
+.It Dv BHND_CAP_BP64
+The backplane supports 64-bit addressing.
+.It Dv BHND_CAP_PMU
+PMU is present.
 .El
 .Pp
 Additional symbolic constants for known

Modified: head/sys/dev/bhnd/bcma/bcma_erom.c
==============================================================================
--- head/sys/dev/bhnd/bcma/bcma_erom.c	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bcma/bcma_erom.c	Thu Mar 29 19:44:15 2018	(r331744)
@@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 #include <machine/resource.h>
 
-#include <dev/bhnd/cores/chipc/chipcreg.h>
+#include <dev/bhnd/bhnd_eromvar.h>
 
 #include "bcma_eromreg.h"
 #include "bcma_eromvar.h"
@@ -168,23 +168,16 @@ static int
 bcma_erom_probe(bhnd_erom_class_t *cls, struct bhnd_erom_io *eio,
     const struct bhnd_chipid *hint, struct bhnd_chipid *cid)
 {
-	uint32_t idreg, eromptr;
+	int error;
 
 	/* Hints aren't supported; all BCMA devices have a ChipCommon
 	 * core */
 	if (hint != NULL)
 		return (EINVAL);
 
-	/* Confirm CHIPC_EROMPTR availability */	
-	idreg = bhnd_erom_io_read(eio, CHIPC_ID, 4);
-	if (!BHND_CHIPTYPE_HAS_EROM(CHIPC_GET_BITS(idreg, CHIPC_ID_BUS)))
-		return (ENXIO);
-
-	/* Fetch EROM address */
-	eromptr = bhnd_erom_io_read(eio, CHIPC_EROMPTR, 4);
-
-	/* Parse chip identifier */
-	*cid = bhnd_parse_chipid(idreg, eromptr);
+	/* Read and parse chip identification */
+	if ((error = bhnd_erom_read_chipid(eio, cid)))
+		return (error);
 
 	/* Verify chip type */
 	switch (cid->chip_type) {

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhnd.h	Thu Mar 29 19:44:15 2018	(r331744)
@@ -219,6 +219,7 @@ struct bhnd_chipid {
 	uint8_t		chip_rev;	/**< chip revision */
 	uint8_t		chip_pkg;	/**< chip package (BHND_PKGID_*) */
 	uint8_t		chip_type;	/**< chip type (BHND_CHIPTYPE_*) */
+	uint32_t	chip_caps;	/**< chip capabilities (BHND_CAP_*) */
 
 	bhnd_addr_t	enum_addr;	/**< chip_type-specific enumeration
 					  *  address; either the siba(4) base
@@ -230,6 +231,15 @@ struct bhnd_chipid {
 };
 
 /**
+ * Chip capabilities
+ */
+enum bhnd_cap {
+	BHND_CAP_BP64	= (1<<0),	/**< Backplane supports 64-bit
+					  *  addressing */
+	BHND_CAP_PMU	= (1<<1),	/**< PMU is present */
+};
+
+/**
  * A bhnd(4) core descriptor.
  */
 struct bhnd_core_info {
@@ -519,18 +529,6 @@ int				 bhnd_alloc_resources(device_t dev,
 void				 bhnd_release_resources(device_t dev,
 				     const struct resource_spec *rs,
 				     struct bhnd_resource **res);
-
-struct bhnd_chipid		 bhnd_parse_chipid(uint32_t idreg,
-				     bhnd_addr_t enum_addr);
-
-int				 bhnd_chipid_fixed_ncores(
-				     const struct bhnd_chipid *cid,
-				     uint16_t chipc_hwrev, uint8_t *ncores);
-
-int				 bhnd_read_chipid(device_t dev,
-				     struct resource_spec *rs,
-				     bus_size_t chipc_offset,
-				     struct bhnd_chipid *result);
 
 void				 bhnd_set_custom_core_desc(device_t dev,
 				     const char *name);

Modified: head/sys/dev/bhnd/bhnd_erom.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_erom.c	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhnd_erom.c	Thu Mar 29 19:44:15 2018	(r331744)
@@ -44,18 +44,26 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <machine/resource.h>
 
+#include <dev/bhnd/bhndreg.h>
 #include <dev/bhnd/bhndvar.h>
+
 #include <dev/bhnd/bhnd_erom.h>
 #include <dev/bhnd/bhnd_eromvar.h>
 
+#include <dev/bhnd/cores/chipc/chipcreg.h>
+
 static int	bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
 		    bhnd_size_t size);
+static int	bhnd_erom_iores_tell(struct bhnd_erom_io *eio,
+		    bhnd_addr_t *addr, bhnd_size_t *size);
 static uint32_t	bhnd_erom_iores_read(struct bhnd_erom_io *eio,
 		    bhnd_size_t offset, u_int width);
 static void	bhnd_erom_iores_fini(struct bhnd_erom_io *eio);
 
 static int	bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
 		    bhnd_size_t size);
+static int	bhnd_erom_iobus_tell(struct bhnd_erom_io *eio,
+		    bhnd_addr_t *addr, bhnd_size_t *size);
 static uint32_t	bhnd_erom_iobus_read(struct bhnd_erom_io *eio,
 		    bhnd_size_t offset, u_int width);
 
@@ -248,7 +256,63 @@ bhnd_erom_free(bhnd_erom_t *erom)
 	kobj_delete((kobj_t)erom, M_BHND);
 }
 
+/**
+ * Read the chip identification registers mapped by @p eio, popuating @p cid
+ * with the parsed result
+ * 
+ * @param	eio		A bus I/O instance, configured with a mapping
+ *				of the ChipCommon core.
+ * @param[out]	cid		On success, the parsed chip identification.
+ *
+ * @warning
+ * On early siba(4) devices, the ChipCommon core does not provide
+ * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions
+ * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return
+ * an invalid `ncores` value.
+ */
+int
+bhnd_erom_read_chipid(struct bhnd_erom_io *eio, struct bhnd_chipid *cid)
+{
+	bhnd_addr_t	cc_addr;
+	bhnd_size_t	cc_size;
+	uint32_t	idreg, cc_caps;
+	int		error;
 
+	/* Fetch ChipCommon address */
+	if ((error = bhnd_erom_io_tell(eio, &cc_addr, &cc_size)))
+		return (error);
+
+	/* Read chip identifier */
+	idreg = bhnd_erom_io_read(eio, CHIPC_ID, 4);
+
+	/* Extract the basic chip info */
+	cid->chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP);
+	cid->chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG);
+	cid->chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV);
+	cid->chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS);
+	cid->ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE);
+
+	/* Populate EROM address */
+	if (BHND_CHIPTYPE_HAS_EROM(cid->chip_type)) {
+		cid->enum_addr = bhnd_erom_io_read(eio, CHIPC_EROMPTR, 4);
+	} else {
+		cid->enum_addr = cc_addr;
+	}
+
+	/* Populate capability flags */
+	cc_caps = bhnd_erom_io_read(eio, CHIPC_CAPABILITIES, 4);
+	cid->chip_caps = 0x0;
+
+	if (cc_caps & CHIPC_CAP_BKPLN64)
+		cid->chip_caps |= BHND_CAP_BP64;
+
+	if (cc_caps & CHIPC_CAP_PMU)
+		cid->chip_caps |= BHND_CAP_PMU;
+
+	return (0);
+}
+
+
 /**
  * Attempt to map @p size bytes at @p addr, replacing any existing
  * @p eio mapping.
@@ -268,6 +332,23 @@ bhnd_erom_io_map(struct bhnd_erom_io *eio, bhnd_addr_t
 }
 
 /**
+ * Return the address range mapped by @p eio, if any.
+ * 
+ * @param	eio	I/O instance state.
+ * @param[out]	addr	The address mapped by @p eio.
+ * @param[out]	size	The number of bytes mapped at @p addr.
+ * 
+ * @retval	0	success
+ * @retval	ENXIO	if @p eio has no mapping.
+ */
+int
+bhnd_erom_io_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
+    bhnd_size_t *size)
+{
+	return (eio->tell(eio, addr, size));
+}
+
+/**
  * Read a 1, 2, or 4 byte data item from @p eio, at the given @p offset
  * relative to @p eio's current mapping.
  * 
@@ -306,6 +387,7 @@ bhnd_erom_iores_new(device_t dev, int rid)
 
 	iores = malloc(sizeof(*iores), M_BHND, M_WAITOK | M_ZERO);
 	iores->eio.map = bhnd_erom_iores_map;
+	iores->eio.tell = bhnd_erom_iores_tell;
 	iores->eio.read = bhnd_erom_iores_read;
 	iores->eio.fini = bhnd_erom_iores_fini;
 
@@ -361,6 +443,21 @@ bhnd_erom_iores_map(struct bhnd_erom_io *eio, bhnd_add
 	return (0);
 }
 
+static int
+bhnd_erom_iores_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
+    bhnd_size_t *size)
+{
+	struct bhnd_erom_iores *iores = (struct bhnd_erom_iores *)eio;
+
+	if (iores->mapped == NULL)
+		return (ENXIO);
+
+	*addr = rman_get_start(iores->mapped->res);
+	*size = rman_get_size(iores->mapped->res);
+
+	return (0);
+}
+
 static uint32_t
 bhnd_erom_iores_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
 {
@@ -416,6 +513,7 @@ bhnd_erom_iobus_init(struct bhnd_erom_iobus *iobus, bh
     bhnd_size_t size, bus_space_tag_t bst, bus_space_handle_t bsh)
 {
 	iobus->eio.map = bhnd_erom_iobus_map;
+	iobus->eio.tell = bhnd_erom_iobus_tell;
 	iobus->eio.read = bhnd_erom_iobus_read;
 	iobus->eio.fini = NULL;
 
@@ -459,6 +557,21 @@ bhnd_erom_iobus_map(struct bhnd_erom_io *eio, bhnd_add
 	iobus->offset = addr - iobus->addr;
 	iobus->limit = size;
 	iobus->mapped = true;
+
+	return (0);
+}
+
+static int
+bhnd_erom_iobus_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
+    bhnd_size_t *size)
+{
+	struct bhnd_erom_iobus *iobus = (struct bhnd_erom_iobus *)eio;
+
+	if (!iobus->mapped)
+		return (ENXIO);
+
+	*addr = iobus->addr + iobus->offset;
+	*size = iobus->limit;
 
 	return (0);
 }

Modified: head/sys/dev/bhnd/bhnd_erom.h
==============================================================================
--- head/sys/dev/bhnd/bhnd_erom.h	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhnd_erom.h	Thu Mar 29 19:44:15 2018	(r331744)
@@ -76,6 +76,8 @@ int			 bhnd_erom_iobus_init(struct bhnd_erom_iobus *io
 
 int			 bhnd_erom_io_map(struct bhnd_erom_io *eio,
 			     bhnd_addr_t addr, bhnd_size_t size);
+int			 bhnd_erom_io_tell(struct bhnd_erom_io *eio,
+			     bhnd_addr_t *addr, bhnd_size_t *size);
 uint32_t		 bhnd_erom_io_read(struct bhnd_erom_io *eio,
 			     bhnd_size_t offset, u_int width);
 void			 bhnd_erom_io_fini(struct bhnd_erom_io *eio);

Modified: head/sys/dev/bhnd/bhnd_eromvar.h
==============================================================================
--- head/sys/dev/bhnd/bhnd_eromvar.h	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhnd_eromvar.h	Thu Mar 29 19:44:15 2018	(r331744)
@@ -48,6 +48,10 @@ struct bhnd_erom_iobus;
 typedef int		(bhnd_erom_io_map_t)(struct bhnd_erom_io *eio,
 			     bhnd_addr_t addr, bhnd_size_t size);
 
+/** @see bhnd_erom_io_tell() */
+typedef int		(bhnd_erom_io_tell_t)(struct bhnd_erom_io *eio,
+			     bhnd_addr_t *addr, bhnd_size_t *size);
+
 /** @see bhnd_erom_io_read() */
 typedef uint32_t	(bhnd_erom_io_read_t)(struct bhnd_erom_io *eio,
 			     bhnd_size_t offset, u_int width);
@@ -55,11 +59,17 @@ typedef uint32_t	(bhnd_erom_io_read_t)(struct bhnd_ero
 /** @see bhnd_erom_io_fini() */
 typedef void		(bhnd_erom_io_fini_t)(struct bhnd_erom_io *eio);
 
+
+int			 bhnd_erom_read_chipid(struct bhnd_erom_io *eio,
+			     struct bhnd_chipid *cid);
+
+
 /**
  * Abstract EROM bus I/O support.
  */
 struct bhnd_erom_io {
 	bhnd_erom_io_map_t	*map;	/**< @see bhnd_erom_io_map() */
+	bhnd_erom_io_tell_t	*tell;	/**< @see bhnd_erom_io_tell() */
 	bhnd_erom_io_read_t	*read;	/**< @see bhnd_erom_io_read() */
 	bhnd_erom_io_fini_t	*fini;	/**< @see bhnd_erom_io_fini(). May be NULL */
 };

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhnd_subr.c	Thu Mar 29 19:44:15 2018	(r331744)
@@ -1057,174 +1057,6 @@ bhnd_release_resources(device_t dev, const struct reso
 }
 
 /**
- * Parse the CHIPC_ID_* fields from the ChipCommon CHIPC_ID
- * register, returning its bhnd_chipid representation.
- * 
- * @param idreg The CHIPC_ID register value.
- * @param enum_addr The enumeration address to include in the result.
- *
- * @warning
- * On early siba(4) devices, the ChipCommon core does not provide
- * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions
- * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return
- * an invalid `ncores` value.
- */
-struct bhnd_chipid
-bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr)
-{
-	struct bhnd_chipid result;
-
-	/* Fetch the basic chip info */
-	result.chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP);
-	result.chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG);
-	result.chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV);
-	result.chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS);
-	result.ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE);
-
-	result.enum_addr = enum_addr;
-
-	return (result);
-}
-
-
-/**
- * Determine the correct core count for a chip identification value that
- * may contain an invalid core count.
- * 
- * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon
- * core does not provide a valid CHIPC_ID_NUMCORE field.
- * 
- * @param cid The chip identification to be queried.
- * @param chipc_hwrev The hardware revision of the ChipCommon core from which
- * @p cid was parsed.
- * @param[out] ncores On success, will be set to the correct core count.
- * 
- * @retval 0 If the core count is already correct, or was mapped to a
- * a correct value.
- * @retval EINVAL If the core count is incorrect, but the chip was not
- * recognized.
- */
-int
-bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev,
-    uint8_t *ncores)
-{
-	/* bcma(4), and most siba(4) devices */
-	if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) {
-		*ncores = cid->ncores;
-		return (0);
-	}
-
-	/* broken siba(4) chipsets */
-	switch (cid->chip_id) {
-	case BHND_CHIPID_BCM4306:
-		*ncores = 6;
-		break;
-	case BHND_CHIPID_BCM4704:
-		*ncores = 9;
-		break;
-	case BHND_CHIPID_BCM5365:
-		/*
-		* BCM5365 does support ID_NUMCORE in at least
-		* some of its revisions, but for unknown
-		* reasons, Broadcom's drivers always exclude
-		* the ChipCommon revision (0x5) used by BCM5365
-		* from the set of revisions supporting
-		* ID_NUMCORE, and instead supply a fixed value.
-		* 
-		* Presumably, at least some of these devices
-		* shipped with a broken ID_NUMCORE value.
-		*/
-		*ncores = 7;
-		break;
-	default:
-		return (EINVAL);
-	}
-
-	return (0);
-}
-
-/**
- * Allocate the resource defined by @p rs via @p dev, use it
- * to read the ChipCommon ID register relative to @p chipc_offset,
- * then release the resource.
- * 
- * @param dev The device owning @p rs.
- * @param rs A resource spec that encompasses the ChipCommon register block.
- * @param chipc_offset The offset of the ChipCommon registers within @p rs.
- * @param[out] result The chip identification data.
- * 
- * @retval 0 success
- * @retval non-zero if the ChipCommon identification data could not be read.
- */
-int
-bhnd_read_chipid(device_t dev, struct resource_spec *rs,
-    bus_size_t chipc_offset, struct bhnd_chipid *result)
-{
-	struct resource			*res;
-	bhnd_addr_t			 enum_addr;
-	uint32_t			 reg;
-	uint8_t				 chip_type;
-	int				 error, rid, rtype;
-
-	rid = rs->rid;
-	rtype = rs->type;
-	error = 0;
-
-	/* Allocate the ChipCommon window resource and fetch the chipid data */
-	res = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
-	if (res == NULL) {
-		device_printf(dev,
-		    "failed to allocate bhnd chipc resource\n");
-		return (ENXIO);
-	}
-
-	/* Fetch the basic chip info */
-	reg = bus_read_4(res, chipc_offset + CHIPC_ID);
-	chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS);
-
-	/* Fetch the EROMPTR */
-	if (BHND_CHIPTYPE_HAS_EROM(chip_type)) {
-		enum_addr = bus_read_4(res, chipc_offset + CHIPC_EROMPTR);
-	} else if (chip_type == BHND_CHIPTYPE_SIBA) {
-		/* siba(4) uses the ChipCommon base address as the enumeration
-		 * address */
-		enum_addr = BHND_DEFAULT_CHIPC_ADDR;
-	} else {
-		device_printf(dev, "unknown chip type %hhu\n", chip_type);
-		error = ENODEV;
-		goto cleanup;
-	}
-
-	*result = bhnd_parse_chipid(reg, enum_addr);
-
-	/* Fix the core count on early siba(4) devices */
-	if (chip_type == BHND_CHIPTYPE_SIBA) {
-		uint32_t	idh;
-		uint16_t	chipc_hwrev;
-
-		/* 
-		 * We need the ChipCommon revision to determine whether
-		 * the ncore field is valid.
-		 * 
-		 * We can safely assume the siba IDHIGH register is mapped
-		 * within the chipc register block.
-		 */
-		idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
-		chipc_hwrev = SIBA_IDH_CORE_REV(idh);
-
-		error = bhnd_chipid_fixed_ncores(result, chipc_hwrev,
-		    &result->ncores);
-		if (error)
-			goto cleanup;
-	}
-
-cleanup:
-	/* Clean up */
-	bus_release_resource(dev, rtype, rid, res);
-	return (error);
-}
-
-/**
  * Allocate and return a new per-core PMU clock control/status (clkctl)
  * instance for @p dev.
  * 

Modified: head/sys/dev/bhnd/bhndb/bhndb_pci.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c	Thu Mar 29 19:44:15 2018	(r331744)
@@ -125,6 +125,8 @@ static void		bhndb_pci_eio_init(struct bhndb_pci_eio *
 			    struct bhndb_pci_probe *probe);
 static int		bhndb_pci_eio_map(struct bhnd_erom_io *eio,
 			    bhnd_addr_t addr, bhnd_size_t size);
+static int		bhndb_pci_eio_tell(struct bhnd_erom_io *eio,
+			    bhnd_addr_t *addr, bhnd_size_t *size);
 static uint32_t		bhndb_pci_eio_read(struct bhnd_erom_io *eio,
 			    bhnd_size_t offset, u_int width);
 
@@ -144,6 +146,7 @@ static struct bhndb_pci_core bhndb_pci_cores[] = {
 /* bhndb_pci erom I/O instance state */
 struct bhndb_pci_eio {
 	struct bhnd_erom_io		 eio;
+	bool				 mapped;	/**< true if a valid mapping exists */
 	bhnd_addr_t			 addr;		/**< mapped address */
 	bhnd_size_t			 size;		/**< mapped size */
 	struct bhndb_pci_probe		*probe;		/**< borrowed probe reference */
@@ -1667,9 +1670,11 @@ bhndb_pci_eio_init(struct bhndb_pci_eio *pio, struct b
 	memset(pio, 0, sizeof(*pio));
 
 	pio->eio.map = bhndb_pci_eio_map;
+	pio->eio.tell = bhndb_pci_eio_tell;
 	pio->eio.read = bhndb_pci_eio_read;
 	pio->eio.fini = NULL;
 
+	pio->mapped = false;
 	pio->addr = 0;
 	pio->size = 0;
 	pio->probe = probe;
@@ -1687,22 +1692,43 @@ bhndb_pci_eio_map(struct bhnd_erom_io *eio, bhnd_addr_
 
 	pio->addr = addr;
 	pio->size = size;
+	pio->mapped = true;
 
 	return (0);
 }
 
+/* bhnd_erom_io_tell() implementation */
+static int
+bhndb_pci_eio_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
+    bhnd_size_t *size)
+{
+	struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
+
+	if (!pio->mapped)
+		return (ENXIO);
+
+	*addr = pio->addr;
+	*size = pio->size;
+
+	return (0);
+}
+
 /* bhnd_erom_io_read() implementation */
 static uint32_t
 bhndb_pci_eio_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
 {
 	struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
 
+	/* Must have a valid mapping */
+	if (!pio->mapped) 
+		panic("no active mapping");
+
 	/* The requested subrange must fall within the existing mapped range */
 	if (offset > pio->size ||
 	    width > pio->size ||
 	    pio->size - offset < width)
 	{
-		return (ENXIO);
+		panic("invalid offset %#jx", offset);
 	}
 
 	return (bhndb_pci_probe_read(pio->probe, pio->addr, offset, width));

Modified: head/sys/dev/bhnd/siba/siba_erom.c
==============================================================================
--- head/sys/dev/bhnd/siba/siba_erom.c	Thu Mar 29 19:43:29 2018	(r331743)
+++ head/sys/dev/bhnd/siba/siba_erom.c	Thu Mar 29 19:44:15 2018	(r331744)
@@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 
-#include <dev/bhnd/bhnd_erom.h>
+#include <dev/bhnd/bhnd_eromvar.h>
 
 #include <dev/bhnd/cores/chipc/chipcreg.h>
 
@@ -390,7 +390,6 @@ siba_eio_read_chipid(struct siba_erom_io *io, bus_addr
     struct bhnd_chipid *cid)
 {
 	struct siba_core_id	ccid;
-	uint32_t		idreg;
 	int			error;
 
 	/* Identify the chipcommon core */
@@ -409,12 +408,39 @@ siba_eio_read_chipid(struct siba_erom_io *io, bus_addr
 	}
 
 	/* Identify the chipset */
-	idreg = siba_eio_read_4(io, 0, CHIPC_ID);
-	*cid = bhnd_parse_chipid(idreg, enum_addr);
+	if ((error = bhnd_erom_read_chipid(io->eio, cid)))
+		return (error);
 
-	/* Fix up the core count in-place */
-	return (bhnd_chipid_fixed_ncores(cid, ccid.core_info.hwrev,
-	    &cid->ncores));
+	/* Do we need to fix up the core count? */
+	if (CHIPC_NCORES_MIN_HWREV(ccid.core_info.hwrev))
+		return (0);
+
+	switch (cid->chip_id) {
+	case BHND_CHIPID_BCM4306:
+		cid->ncores = 6;
+		break;
+	case BHND_CHIPID_BCM4704:
+		cid->ncores = 9;
+		break;
+	case BHND_CHIPID_BCM5365:
+		/*
+		* BCM5365 does support ID_NUMCORE in at least
+		* some of its revisions, but for unknown
+		* reasons, Broadcom's drivers always exclude
+		* the ChipCommon revision (0x5) used by BCM5365
+		* from the set of revisions supporting
+		* ID_NUMCORE, and instead supply a fixed value.
+		* 
+		* Presumably, at least some of these devices
+		* shipped with a broken ID_NUMCORE value.
+		*/
+		cid->ncores = 7;
+		break;
+	default:
+		return (EINVAL);
+	}
+
+	return (0);
 }
 
 static int


More information about the svn-src-head mailing list