bhnd(4): Add a bhnd bus method for fetching the device's core table.
This will allow us to perform bhndb(4) bridge configuration based on the identified hardware, prior to performing full enumeration of the child bhnd bus. Approved by: adrian (mentor, implicit)
This commit is contained in:
parent
27a465b033
commit
203788adf0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304963
@ -492,6 +492,42 @@ bcma_free_bhnd_dinfo(device_t dev, struct bhnd_devinfo *dinfo)
|
||||
bcma_free_dinfo(dev, (struct bcma_devinfo *)dinfo);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bcma_get_core_table(device_t dev, device_t child, struct bhnd_core_info **cores,
|
||||
u_int *num_cores)
|
||||
{
|
||||
struct bcma_softc *sc;
|
||||
struct bcma_erom erom;
|
||||
const struct bhnd_chipid *cid;
|
||||
struct resource *r;
|
||||
int error;
|
||||
int rid;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/* Map the EROM table. */
|
||||
cid = BHND_BUS_GET_CHIPID(dev, dev);
|
||||
rid = 0;
|
||||
r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, cid->enum_addr,
|
||||
cid->enum_addr + BCMA_EROM_TABLE_SIZE, BCMA_EROM_TABLE_SIZE,
|
||||
RF_ACTIVE);
|
||||
if (r == NULL) {
|
||||
device_printf(dev, "failed to allocate EROM resource\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Enumerate all declared cores */
|
||||
if ((error = bcma_erom_open(&erom, r, BCMA_EROM_TABLE_START)))
|
||||
goto cleanup;
|
||||
|
||||
error = bcma_erom_get_core_info(&erom, cores, num_cores);
|
||||
|
||||
cleanup:
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan a device enumeration ROM table, adding all valid discovered cores to
|
||||
* the bus.
|
||||
@ -577,6 +613,7 @@ static device_method_t bcma_methods[] = {
|
||||
DEVMETHOD(bhnd_bus_find_hostb_device, bcma_find_hostb_device),
|
||||
DEVMETHOD(bhnd_bus_alloc_devinfo, bcma_alloc_bhnd_dinfo),
|
||||
DEVMETHOD(bhnd_bus_free_devinfo, bcma_free_bhnd_dinfo),
|
||||
DEVMETHOD(bhnd_bus_get_core_table, bcma_get_core_table),
|
||||
DEVMETHOD(bhnd_bus_reset_core, bcma_reset_core),
|
||||
DEVMETHOD(bhnd_bus_suspend_core, bcma_suspend_core),
|
||||
DEVMETHOD(bhnd_bus_read_config, bcma_read_config),
|
||||
|
@ -424,6 +424,32 @@ bhnd_get_chipid(device_t dev) {
|
||||
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a list of all cores discoverable on the bhnd bus.
|
||||
*
|
||||
* Enumerates all cores discoverable on @p dev, returning the list in
|
||||
* @p cores and the count in @p num_cores.
|
||||
*
|
||||
* The memory allocated for the list should be freed using
|
||||
* `free(*cores, M_BHND)`. @p cores and @p num_cores are not changed
|
||||
* when an error is returned.
|
||||
*
|
||||
* @param dev A bhnd bus child device.
|
||||
* @param[out] cores The table of core descriptors.
|
||||
* @param[out] num_cores The number of core descriptors in @p cores.
|
||||
*
|
||||
* @retval 0 success
|
||||
* @retval non-zero if an error occurs enumerating @p dev, a regular UNIX
|
||||
* error code should be returned.
|
||||
*/
|
||||
static inline int
|
||||
bhnd_get_core_table(device_t dev, struct bhnd_core_info **cores,
|
||||
u_int *num_cores)
|
||||
{
|
||||
return (BHND_BUS_GET_CORE_TABLE(device_get_parent(dev), dev, cores,
|
||||
num_cores));
|
||||
}
|
||||
|
||||
/**
|
||||
* If supported by the chipset, return the clock source for the given clock.
|
||||
*
|
||||
|
@ -56,6 +56,13 @@ CODE {
|
||||
panic("bhnd_bus_get_chipid unimplemented");
|
||||
}
|
||||
|
||||
static int
|
||||
bhnd_bus_null_get_core_table(device_t dev, device_t child,
|
||||
struct bhnd_core_info **cores, u_int *num_cores)
|
||||
{
|
||||
panic("bhnd_bus_get_core_table unimplemented");
|
||||
}
|
||||
|
||||
static bhnd_attach_type
|
||||
bhnd_bus_null_get_attach_type(device_t dev, device_t child)
|
||||
{
|
||||
@ -270,6 +277,32 @@ METHOD const struct bhnd_chipid * get_chipid {
|
||||
device_t child;
|
||||
} DEFAULT bhnd_bus_null_get_chipid;
|
||||
|
||||
/**
|
||||
* Get a list of all cores discoverable on @p dev.
|
||||
*
|
||||
* Enumerates all cores discoverable on @p dev, returning the list in
|
||||
* @p cores and the count in @p num_cores.
|
||||
*
|
||||
* The memory allocated for the list should be freed using
|
||||
* `free(*cores, M_BHND)`. @p cores and @p num_cores are not changed
|
||||
* when an error is returned.
|
||||
*
|
||||
* @param dev The bhnd bus device.
|
||||
* @param child The requesting bhnd bus child.
|
||||
* @param[out] cores The table of core descriptors.
|
||||
* @param[out] num_cores The number of core descriptors in @p cores.
|
||||
*
|
||||
* @retval 0 success
|
||||
* @retval non-zero if an error occurs enumerating @p dev, a regular UNIX
|
||||
* error code should be returned.
|
||||
*/
|
||||
METHOD int get_core_table {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
struct bhnd_core_info **cores;
|
||||
u_int *num_cores;
|
||||
} DEFAULT bhnd_bus_null_get_core_table;
|
||||
|
||||
/**
|
||||
* Return the BHND attachment type of the parent bus.
|
||||
*
|
||||
|
@ -504,6 +504,76 @@ siba_free_bhnd_dinfo(device_t dev, struct bhnd_devinfo *dinfo)
|
||||
siba_free_dinfo(dev, (struct siba_devinfo *)dinfo);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
siba_get_core_table(device_t dev, device_t child, struct bhnd_core_info **cores,
|
||||
u_int *num_cores)
|
||||
{
|
||||
const struct bhnd_chipid *chipid;
|
||||
struct bhnd_core_info *table;
|
||||
struct bhnd_resource *r;
|
||||
int error;
|
||||
int rid;
|
||||
|
||||
/* Fetch the core count from our chip identification */
|
||||
chipid = BHND_BUS_GET_CHIPID(dev, dev);
|
||||
|
||||
/* Allocate our local core table */
|
||||
table = malloc(sizeof(*table) * chipid->ncores, M_BHND, M_NOWAIT);
|
||||
if (table == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
/* Enumerate all cores. */
|
||||
for (u_int i = 0; i < chipid->ncores; i++) {
|
||||
struct siba_core_id cid;
|
||||
uint32_t idhigh, idlow;
|
||||
|
||||
/* Map the core's register block */
|
||||
rid = 0;
|
||||
r = bhnd_alloc_resource(dev, SYS_RES_MEMORY, &rid,
|
||||
SIBA_CORE_ADDR(i), SIBA_CORE_ADDR(i) + SIBA_CORE_SIZE - 1,
|
||||
SIBA_CORE_SIZE, RF_ACTIVE);
|
||||
if (r == NULL) {
|
||||
error = ENXIO;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Read the core info */
|
||||
idhigh = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
|
||||
idlow = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW));
|
||||
|
||||
cid = siba_parse_core_id(idhigh, idlow, i, 0);
|
||||
table[i] = cid.core_info;
|
||||
|
||||
/* Determine unit number */
|
||||
for (u_int j = 0; j < i; j++) {
|
||||
if (table[j].vendor == table[i].vendor &&
|
||||
table[j].device == table[i].device)
|
||||
table[i].unit++;
|
||||
}
|
||||
|
||||
/* Release our resource */
|
||||
bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r);
|
||||
r = NULL;
|
||||
}
|
||||
|
||||
/* Provide the result values (performed last to avoid modifying
|
||||
* cores/num_cores if enumeration failed). */
|
||||
*cores = table;
|
||||
*num_cores = chipid->ncores;
|
||||
|
||||
return (0);
|
||||
|
||||
failed:
|
||||
if (table != NULL)
|
||||
free(table, M_BHND);
|
||||
|
||||
if (r != NULL)
|
||||
bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the core table and add all valid discovered cores to
|
||||
* the bus.
|
||||
@ -696,6 +766,7 @@ static device_method_t siba_methods[] = {
|
||||
|
||||
/* BHND interface */
|
||||
DEVMETHOD(bhnd_bus_find_hostb_device, siba_find_hostb_device),
|
||||
DEVMETHOD(bhnd_bus_get_core_table, siba_get_core_table),
|
||||
DEVMETHOD(bhnd_bus_alloc_devinfo, siba_alloc_bhnd_dinfo),
|
||||
DEVMETHOD(bhnd_bus_free_devinfo, siba_free_bhnd_dinfo),
|
||||
DEVMETHOD(bhnd_bus_reset_core, siba_reset_core),
|
||||
|
Loading…
Reference in New Issue
Block a user