Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Aug 2016 20:39:53 +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: r304967 - in head/sys/dev/bhnd: . siba
Message-ID:  <201608282039.u7SKdrO9050847@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: landonf
Date: Sun Aug 28 20:39:53 2016
New Revision: 304967
URL: https://svnweb.freebsd.org/changeset/base/304967

Log:
  bhnd(4): Apply the siba chipid ncore fixup in bhnd_read_chipid(), ensuring
  that bhndb et al are always operating on a valid core count.
  
  Approved by:	adrian (mentor, implicit)

Modified:
  head/sys/dev/bhnd/bhnd.h
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/siba/siba.c

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Sun Aug 28 20:39:33 2016	(r304966)
+++ head/sys/dev/bhnd/bhnd.h	Sun Aug 28 20:39:53 2016	(r304967)
@@ -317,6 +317,10 @@ void				 bhnd_release_resources(device_t
 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,

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Sun Aug 28 20:39:33 2016	(r304966)
+++ head/sys/dev/bhnd/bhnd_subr.c	Sun Aug 28 20:39:53 2016	(r304967)
@@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/rman.h>
 #include <machine/resource.h>
 
+#include <dev/bhnd/siba/sibareg.h>
+
 #include <dev/bhnd/cores/chipc/chipcreg.h>
 
 #include "nvram/bhnd_nvram.h"
@@ -840,6 +842,63 @@ bhnd_parse_chipid(uint32_t idreg, bhnd_a
 	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,
@@ -894,6 +953,27 @@ bhnd_read_chipid(device_t dev, struct re
 
 	*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);

Modified: head/sys/dev/bhnd/siba/siba.c
==============================================================================
--- head/sys/dev/bhnd/siba/siba.c	Sun Aug 28 20:39:33 2016	(r304966)
+++ head/sys/dev/bhnd/siba/siba.c	Sun Aug 28 20:39:53 2016	(r304967)
@@ -635,35 +635,12 @@ siba_add_children(device_t dev, const st
 		ccreg = bus_read_4(r, CHIPC_ID);
 		ccid = bhnd_parse_chipid(ccreg, SIBA_ENUM_ADDR);
 
-		if (!CHIPC_NCORES_MIN_HWREV(ccrev)) {
-			switch (ccid.chip_id) {
-			case BHND_CHIPID_BCM4306:
-				ccid.ncores = 6;
-				break;
-			case BHND_CHIPID_BCM4704:
-				ccid.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.
-				*/
-				ccid.ncores = 7;
-				break;
-			default:
-				device_printf(dev, "unable to determine core "
-				    "count for unrecognized chipset 0x%hx\n",
-				    ccid.chip_id);
-				error = ENXIO;
-				goto cleanup;
-			}
+		/* Fix up the core count */
+		error = bhnd_chipid_fixed_ncores(&ccid, ccrev, &ccid.ncores);
+		if (error) {
+			device_printf(dev, "unable to determine core count for "
+			    "chipset 0x%hx\n", ccid.chip_id);
+			goto cleanup;
 		}
 
 		chipid = &ccid;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608282039.u7SKdrO9050847>