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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to