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);
_______________________________________________
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