[fdt] Generalise access to "reg" property

The "reg" property is also used by non-device nodes, such as the nodes
describing the system memory map.

Provide generalised functionality for parsing the "#address-cells",
"#size-cells", and "reg" properties.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-05-09 16:26:41 +01:00
parent 3027864f13
commit f988ec09e0
4 changed files with 141 additions and 26 deletions
+7 -16
View File
@@ -56,27 +56,25 @@ void * dt_ioremap ( struct dt_device *dt, unsigned int offset,
unsigned int index, size_t len ) {
struct dt_device *parent =
container_of ( dt->dev.parent, struct dt_device, dev );
struct fdt_reg_cells *regs = &parent->regs;
uint64_t address;
uint64_t size;
unsigned int cell;
void *io_addr;
int rc;
/* Read address */
cell = ( index * ( parent->address_cells + parent->size_cells ) );
if ( ( rc = fdt_cells ( &sysfdt, offset, "reg", cell,
parent->address_cells, &address ) ) != 0 ) {
if ( ( rc = fdt_reg_address ( &sysfdt, offset, regs, index,
&address ) ) != 0 ) {
DBGC ( dt, "DT %s could not read region %d address: %s\n",
dt->path, index, strerror ( rc ) );
return NULL;
}
cell += parent->address_cells;
/* Read size (or assume sufficient, if tree specifies no sizes) */
size = len;
if ( parent->size_cells &&
( rc = fdt_cells ( &sysfdt, offset, "reg", cell,
parent->size_cells, &size ) ) != 0 ) {
if ( regs->size_cells &&
( ( rc = fdt_reg_size ( &sysfdt, offset, regs, index,
&size ) ) != 0 ) ) {
DBGC ( dt, "DT %s could not read region %d size: %s\n",
dt->path, index, strerror ( rc ) );
return NULL;
@@ -225,14 +223,7 @@ static int dt_probe_node ( struct dt_device *parent, unsigned int offset,
list_add_tail ( &dt->dev.siblings, &dt->dev.parent->children );
/* Read #address-cells and #size-cells, if present */
if ( ( rc = fdt_u32 ( &sysfdt, offset, "#address-cells",
&dt->address_cells ) ) != 0 ) {
dt->address_cells = DT_DEFAULT_ADDRESS_CELLS;
}
if ( ( rc = fdt_u32 ( &sysfdt, offset, "#size-cells",
&dt->size_cells ) ) != 0 ) {
dt->size_cells = DT_DEFAULT_SIZE_CELLS;
}
fdt_reg_cells ( &sysfdt, offset, &dt->regs );
/* Probe device */
if ( ( rc = dt_probe ( dt, offset ) ) != 0 )