svn commit: r304967 - in head/sys/dev/bhnd: . siba
Landon J. Fuller
landonf at FreeBSD.org
Sun Aug 28 20:39:55 UTC 2016
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;
More information about the svn-src-head
mailing list