---
name: "bhnd_erom"
section: "9"
platform: "freebsd"
package: "base"
version: "16.0-CURRENT-20261027-61c70dc16a79"
release: "FreeBSD 16.0-CURRENT (2026-10-27)"
platforms: ["freebsd"]
url: "https://new.carta.tech/bhnd_erom"
---

# bhnd\_erom(9)

BHND device enumeration table parsing

## NAME

**bhnd\_erom**, **bhnd\_erom\_alloc**, **bhnd\_erom\_dump**, **bhnd\_erom\_fini\_static**, **bhnd\_erom\_free**, **bhnd\_erom\_free\_core\_table**, **bhnd\_erom\_get\_core\_table**, **bhnd\_erom\_init\_static**, **bhnd\_erom\_io**, **bhnd\_erom\_io\_fini**, **bhnd\_erom\_io\_map**, **bhnd\_erom\_io\_read**, **bhnd\_erom\_iobus\_init**, **bhnd\_erom\_iores\_new**, **bhnd\_erom\_lookup\_core**, **bhnd\_erom\_lookup\_core\_addr**, **bhnd\_erom\_probe**, **bhnd\_erom\_probe\_driver\_classes** – BHND device enumeration table parsing

## SYNOPSIS

**#include \<dev/bhnd/bhnd.h\>**

**#include \<dev/bhnd/bhnd\_erom.h\>**

*typedef* *struct* *bhnd\_erom* *bhnd\_erom\_t*; *typedef* *struct* *kobj\_class* *bhnd\_erom\_class\_t*; *typedef* *struct* *bhnd\_erom\_static* *bhnd\_erom\_static\_t*;

*int*\

**bhnd\_erom\_probe**(*bhnd\_erom\_class\_t \*cls*, *struct bhnd\_erom\_io \*eio*, *const struct bhnd\_chipid \*hint*, *struct bhnd\_chipid \*cid*);

*bhnd\_erom\_class\_t* *\**\

**bhnd\_erom\_probe\_driver\_classes**(*devclass\_t bus\_devclass*, *struct bhnd\_erom\_io \*eio*, *const struct bhnd\_chipid \*hint*, *struct bhnd\_chipid \*cid*);

*bhnd\_erom\_t* *\**\

**bhnd\_erom\_alloc**(*bhnd\_erom\_class\_t \*cls*, *const struct bhnd\_chipid \*cid*, *struct bhnd\_erom\_io \*eio*);

*void*\

**bhnd\_erom\_free**(*bhnd\_erom\_t \*erom*);

*int*\

**bhnd\_erom\_init\_static**(*bhnd\_erom\_class\_t \*cls*, *bhnd\_erom\_t \*erom*, *size\_t esize*, *const struct bhnd\_chipid \*cid*, *struct bhnd\_erom\_io \*eio*);

*void*\

**bhnd\_erom\_fini\_static**(*bhnd\_erom\_t \*erom*);

*int*\

**bhnd\_erom\_dump**(*bhnd\_erom\_t \*erom*);

*int*\

**bhnd\_erom\_get\_core\_table**(*bhnd\_erom\_t \*erom*, *struct bhnd\_core\_info \*\*cores*, *u\_int \*num\_cores*);

*void*\

**bhnd\_erom\_free\_core\_table**(*bhnd\_erom\_t \*erom*, *struct bhnd\_core\_info \*cores*);

*int*\

**bhnd\_erom\_lookup\_core**(*bhnd\_erom\_t \*erom*, *const struct bhnd\_core\_match \*desc*, *struct bhnd\_core\_info \*core*);

*int*\

**bhnd\_erom\_lookup\_core\_addr**(*bhnd\_erom\_t \*erom*, *const struct bhnd\_core\_match \*desc*, *bhnd\_port\_type type*, *u\_int port*, *u\_int region*, *struct bhnd\_core\_info \*core*, *bhnd\_addr\_t \*addr*, *bhnd\_size\_t \*size*);

### Bus Space I/O

*struct* *bhnd\_erom\_io* *\**\

**bhnd\_erom\_iores\_new**(*device\_t dev*, *int rid*);

*int*\

**bhnd\_erom\_iobus\_init**(*struct bhnd\_erom\_iobus \*iobus*, *bhnd\_addr\_t addr*, *bhnd\_size\_t size*, *bus\_space\_tag\_t bst*, *bus\_space\_handle\_t bsh*);

*void*\

**bhnd\_erom\_io\_fini**(*struct bhnd\_erom\_io \*eio*);

*int*\

**bhnd\_erom\_io\_map**(*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*);

**#include \<dev/bhnd/bhnd\_eromvar.h\>**

```
struct bhnd_erom_io {
	bhnd_erom_io_map_t	*map;
	bhnd_erom_io_read_t	*read;
	bhnd_erom_io_fini_t	*fini;
};
```

*typedef* *int*\

**bhnd\_erom\_io\_map\_t**(*struct bhnd\_erom\_io \*eio*, *bhnd\_addr\_t addr*, *bhnd\_size\_t size*);

*typedef* *uint32\_t*\

**bhnd\_erom\_io\_read\_t**(*struct bhnd\_erom\_io \*eio*, *bhnd\_size\_t offset*, *u\_int width*);

*typedef* *void*\

**bhnd\_erom\_io\_fini\_t**(*struct bhnd\_erom\_io \*eio*);

## DESCRIPTION

The **bhnd\_erom** framework provides a common parser interface to the BHND device enumeration table formats supported by [bhnd(4)](/bhnd/4.md) bus drivers.

The **bhnd\_erom\_probe**() function is used to identify a [bhnd(4)](/bhnd/4.md) bus device and determine whether the erom class *cls* is capable of parsing its device enumeration table. If successful, the probed chip identification is written to the location pointed to by *cid*.

A pointer to a bus I/O instance mapping the device registers of the first hardware core must be provided using the *eio* argument. The registers can be mapped using **bhnd\_erom\_io\_map**().

On devices that do not provide standard [bhnd\_chipc(4)](/bhnd_chipc/4.md) chip identification registers via the first hardware core, a pointer to chip information for the device must be specified using the *hint* argument. Otherwise, the *hint* argument should be NULL.

The **bhnd\_erom\_probe\_driver\_classes**() function is a convenience wrapper for **bhnd\_erom\_probe**(). This function will iterate over all drivers instances in the device class *bus\_devclass*, using [bhnd\_driver\_get\_erom\_class(9)](/bhnd_driver_get_erom_class/9.md) to fetch each driver's erom class and probe the hardware core mapped by *eio*. A pointer to the erom class with the highest probe priority is returned on success. If there are no successful probe results from the erom classes, NULL is returned.

The **bhnd\_erom\_alloc**() function allocates and returns a new parser instance of the device enumeration class *cls* for the chip identified by *cid*, using the bus I/O instance *eio* to map and read the device table. On success, the returned *bhnd\_erom\_t* assumes ownership of *eio*.

The **bhnd\_erom\_free**() function releases all resources held by an erom parser successfully allocated using **bhnd\_erom\_alloc**().

Clients can manage the allocation of memory themselves with **bhnd\_erom\_init\_static**(). This is useful in cases like performing device enumeration before [malloc(9)](/malloc/9.md) initialization. **bhnd\_erom\_init\_static**() is called with *erom* set to a pointer to the memory for the instance, and the total available bytes in *esize*.

The *bhnd\_erom\_static* structure is large enough to statically allocate any supported parser class instance state. Pointers to a *bhnd\_erom\_static* structure can be cast to *bhnd\_erom\_t*.

The **bhnd\_erom\_fini\_static**() function releases all resources held by an erom parser successfully initialized using **bhnd\_erom\_init\_static**().

The **bhnd\_erom\_dump**() function enumerates and prints all device table entries in *erom*.

The **bhnd\_erom\_get\_core\_table**() function enumerates all device table entries in *erom*, returning a table of core information structures in *cores* and the count in *num\_cores*. The memory allocated for the table must be freed using **bhnd\_erom\_free\_core\_table**().

The **bhnd\_erom\_free\_core\_table**() function frees any memory allocated in a previous call to **bhnd\_erom\_get\_core\_table**().

The **bhnd\_erom\_lookup\_core**() function locates the first device table entry in *erom* that matches core match descriptor *desc*, writing the core information of the matching entry to *core*.

The **bhnd\_erom\_lookup\_core\_addr**() function locates the first device table entry in *erom* that matches core match descriptor *desc*, fetching the base address and size of the memory region *region* mapped to the port *port* of type *type*. On success, the core information of the matching entry is written to *core*, the base address of the port region is written to *addr*, and the total size of the port region is written to *size*. If the core information is not desired, set *core* to NULL.

### Bus Space I/O

The *bhnd\_erom\_io* structure provides a set of I/O callbacks used by **bhnd\_erom** to map and read the device enumeration table. Clients may either use the existing **bhnd\_erom\_iores\_new**() or **bhnd\_erom\_iobus\_init**() functions to allocate a bus I/O instance, or implement the *bhnd\_erom\_io* callbacks directly.

The *bhnd\_erom\_io* structure contains these required fields:

- *map*

  A function implementing **bhnd\_erom\_io\_map**().

- *read*

  A function implementing **bhnd\_erom\_io\_read**().

- *fini*

  A function implementing **bhnd\_erom\_io\_fini**().

The **bhnd\_erom\_iores\_new**() function allocates and returns a new bus I/O instance that will perform mapping by using [bhnd\_alloc\_resource(9)](/bhnd_alloc_resource/9.md) to allocate SYS\_RES\_MEMORY bus resources on demand from the device *dev* using a resource ID of *rid*.

The **bhnd\_erom\_iobus\_init**() function initializes a caller-allocated bus I/O instance *iobus* that will perform bus I/O using the bus space tag *bst* and handle *bsh*. The base address and total size mapped by *bsh* should be specified using the *addr* and *size* arguments.

The **bhnd\_erom\_io\_fini**() function frees all resources held by the bus I/O instance *eio*.

The **bhnd\_erom\_io\_map**() function is used to request that the bus I/O instance *eio* map [bhnd(4)](/bhnd/4.md) bus space at bus address *addr* with a mapping of size *size*.

The **bhnd\_erom\_io\_read**() function is used to read a data item of *width* bytes from the bus I/O instance *eio* at *offset*, relative to the bus address previously mapped using **bhnd\_erom\_io\_map**().

The *width* must be one of 1, 2, or 4 bytes.

## RETURN VALUES

The **bhnd\_erom\_probe**() function returns a standard [DEVICE\_PROBE(9)](/DEVICE_PROBE/9.md) result.

A return value equal to or less than zero indicates success. Values greater than zero indicates an error, and will be an appropriate error code. For values less than or equal to zero, the erom class returning the highest value should be used to parse the erom table. ENXIO is returned if the device is not supported by the parser.

The **bhnd\_erom\_probe\_driver\_classes**() function returns a pointer to the probed *bhnd\_erom\_class\_t* instance on success, a null pointer otherwise.

The **bhnd\_erom\_alloc**() function returns a pointer to *bhnd\_erom\_t* on success, or NULL if an error occurred allocating or initializing the EROM parser.

The **bhnd\_erom\_init\_static**() function returns 0 on success, ENOMEM if the allocation size is smaller than required by the erom class, or an appropriate error code if initialization otherwise fails.

The **bhnd\_erom\_lookup\_core**() function returns 0 on success, ENOENT if no matching core is found, or an appropriate error code if parsing the device table otherwise fails.

The **bhnd\_erom\_dump**(), **bhnd\_erom\_get\_core\_table**(), **bhnd\_erom\_iobus\_init**(), **bhnd\_erom\_io\_map**(), functions return 0 on success, otherwise an appropriate error code is returned.

## SEE ALSO

[bhnd(4)](/bhnd/4.md), [bhnd(9)](/bhnd/9.md), [bhnd\_alloc\_resource(9)](/bhnd_alloc_resource/9.md), [bhnd\_driver\_get\_erom\_class(9)](/bhnd_driver_get_erom_class/9.md), [bus\_space(9)](/bus_space/9.md)

## AUTHORS

The **bhnd\_erom** framework and this manual page were written by Landon Fuller ⟨*landonf@FreeBSD.org*⟩.
