/** * Read and parse the chip identification register from the ChipCommon core. * * @param io EROM I/O context. * @param enum_addr The physical address mapped by @p io. * @param cid On success, the parsed chip identifier. */ static int siba_eio_read_chipid(struct siba_erom_io *io, bus_addr_t enum_addr, struct bhnd_chipid *cid) { struct siba_core_id ccid; uint32_t idreg; /* Identify the chipcommon core */ ccid = siba_eio_read_core_id(io, 0, 0); if (ccid.core_info.vendor != BHND_MFGID_BCM || ccid.core_info.device != BHND_COREID_CC) { if (bootverbose) { EROM_LOG(io, "first core not chipcommon " "(vendor=%#hx, core=%#hx)\n", ccid.core_info.vendor, ccid.core_info.device); } return (ENXIO); } /* Identify the chipset */ idreg = siba_eio_read_4(io, 0, CHIPC_ID); *cid = bhnd_parse_chipid(idreg, enum_addr); /* Fix up the core count in-place */ return (bhnd_chipid_fixed_ncores(cid, ccid.core_info.hwrev, &cid->ncores)); }
static int chipc_attach(device_t dev) { struct chipc_softc *sc; bhnd_addr_t enum_addr; uint32_t ccid_reg; uint8_t chip_type; int error; sc = device_get_softc(dev); sc->dev = dev; sc->quirks = bhnd_device_quirks(dev, chipc_devices, sizeof(chipc_devices[0])); /* Allocate bus resources */ memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec)); if ((error = bhnd_alloc_resources(dev, sc->rspec, sc->res))) return (error); sc->core = sc->res[0]; /* Fetch our chipset identification data */ ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID); chip_type = CHIPC_GET_ATTR(ccid_reg, ID_BUS); switch (chip_type) { case BHND_CHIPTYPE_SIBA: /* enumeration space starts at the ChipCommon register base. */ enum_addr = rman_get_start(sc->core->res); break; case BHND_CHIPTYPE_BCMA: case BHND_CHIPTYPE_BCMA_ALT: enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR); break; default: device_printf(dev, "unsupported chip type %hhu\n", chip_type); error = ENODEV; goto cleanup; } sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr); /* Fetch capability and status register values */ sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES); sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST); // TODO switch (bhnd_chipc_nvram_src(dev)) { case BHND_NVRAM_SRC_CIS: device_printf(dev, "NVRAM source: CIS\n"); break; case BHND_NVRAM_SRC_SPROM: device_printf(dev, "NVRAM source: SPROM\n"); break; case BHND_NVRAM_SRC_OTP: device_printf(dev, "NVRAM source: OTP\n"); break; case BHND_NVRAM_SRC_NFLASH: device_printf(dev, "NVRAM source: NFLASH\n"); break; case BHND_NVRAM_SRC_NONE: device_printf(dev, "NVRAM source: NONE\n"); break; } return (0); cleanup: bhnd_release_resources(dev, sc->rspec, sc->res); return (error); }