Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: dt: cached data for fdt_get_reg_props_by_index() #7239

Merged
merged 1 commit into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 19 additions & 51 deletions core/kernel/dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,19 @@ static size_t fdt_read_size(const uint32_t *cell, int n)
return sz;
}

int fdt_reg_info(const void *fdt, int offs, paddr_t *base, size_t *size)
int fdt_get_reg_props_by_index(const void *fdt, int offs, int index,
paddr_t *base, size_t *size)
{
const fdt32_t *reg = NULL;
int addr_ncells = 0;
int size_ncells = 0;
int cell_offset = 0;
int parent = 0;
int len = 0;

if (index < 0)
return -FDT_ERR_BADOFFSET;

reg = (const uint32_t *)fdt_getprop(fdt, offs, "reg", &len);
if (!reg)
return -FDT_ERR_NOTFOUND;
Expand All @@ -215,27 +220,36 @@ int fdt_reg_info(const void *fdt, int offs, paddr_t *base, size_t *size)
return -FDT_ERR_NOTFOUND;
}

if ((size_t)len < addr_ncells * sizeof(*reg))
cell_offset = index * (addr_ncells + size_ncells);

if ((size_t)len < (cell_offset + addr_ncells) * sizeof(*reg))
return -FDT_ERR_BADSTRUCTURE;

if (base) {
*base = fdt_read_paddr(reg, addr_ncells);
*base = fdt_read_paddr(reg + cell_offset, addr_ncells);
if (*base == DT_INFO_INVALID_REG)
return -FDT_ERR_NOTFOUND;
}

if (size) {
if ((size_t)len < (addr_ncells + size_ncells) * sizeof(*reg))
if ((size_t)len <
(cell_offset + addr_ncells + size_ncells) * sizeof(*reg))
return -FDT_ERR_BADSTRUCTURE;

*size = fdt_read_size(reg + addr_ncells, size_ncells);
*size = fdt_read_size(reg + cell_offset + addr_ncells,
size_ncells);
if (*size == DT_INFO_INVALID_REG_SIZE)
return -FDT_ERR_NOTFOUND;
}

return 0;
}

int fdt_reg_info(const void *fdt, int offs, paddr_t *base, size_t *size)
{
return fdt_get_reg_props_by_index(fdt, offs, 0, base, size);
}

paddr_t fdt_reg_base_address(const void *fdt, int offs)
{
paddr_t base = 0;
Expand Down Expand Up @@ -380,52 +394,6 @@ uint32_t fdt_read_uint32_default(const void *fdt, int node,
return ret;
}

int fdt_get_reg_props_by_index(const void *fdt, int node, int index,
paddr_t *base, size_t *size)
{
const fdt32_t *prop = NULL;
int parent = 0;
int len = 0;
int address_cells = 0;
int size_cells = 0;
int cell = 0;

parent = fdt_parent_offset(fdt, node);
if (parent < 0)
return parent;

address_cells = fdt_address_cells(fdt, parent);
if (address_cells < 0)
return address_cells;

size_cells = fdt_size_cells(fdt, parent);
if (size_cells < 0)
return size_cells;

cell = index * (address_cells + size_cells);

prop = fdt_getprop(fdt, node, "reg", &len);
if (!prop)
return len;

if (((cell + address_cells + size_cells) * (int)sizeof(uint32_t)) > len)
return -FDT_ERR_BADVALUE;

if (base) {
*base = fdt_read_paddr(&prop[cell], address_cells);
if (*base == DT_INFO_INVALID_REG)
return -FDT_ERR_BADVALUE;
}

if (size) {
*size = fdt_read_size(&prop[cell + address_cells], size_cells);
if (*size == DT_INFO_INVALID_REG_SIZE)
return -FDT_ERR_BADVALUE;
}

return 0;
}

int fdt_get_reg_props_by_name(const void *fdt, int node, const char *name,
paddr_t *base, size_t *size)
{
Expand Down
Loading