From b66b7f7860a12edbfa8afbedc78f4bce8bd02470 Mon Sep 17 00:00:00 2001 From: Benjamin Doron Date: Tue, 17 Dec 2024 15:46:14 -0500 Subject: [PATCH] commonlib/device_tree.c: Add a function that reads FDT ints Follow the recommendation at https://review.coreboot.org/c/coreboot/+/84796/comment/21f615a2_99a41147/ and implement support for reading integer properties generically, using their size to determine how much to read. This will be used for reading `load`, `entry` and perhaps others. Change-Id: I02d27eb5e23dfbfc1404d209ee8d60968e22bb80 Signed-off-by: Benjamin Doron Reviewed-on: https://review.coreboot.org/c/coreboot/+/85643 Reviewed-by: Maximilian Brune Tested-by: build bot (Jenkins) --- src/commonlib/device_tree.c | 20 +++++++++++++++++++ src/commonlib/include/commonlib/device_tree.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/src/commonlib/device_tree.c b/src/commonlib/device_tree.c index c4fbae986d..fb1e78f590 100644 --- a/src/commonlib/device_tree.c +++ b/src/commonlib/device_tree.c @@ -259,6 +259,26 @@ static u32 fdt_read_cell_props(const void *blob, u32 node_offset, u32 *addrcp, u return offset; } +uint64_t fdt_read_int_prop(struct fdt_property *prop, u32 cells) +{ + if (cells == 0) + cells = prop->size / 4; + + if (cells * 4 != prop->size) { + printk(BIOS_ERR, "FDT integer property of size %u @%p doesn't match expected cell count %u\n", + prop->size, prop->data, cells); + return 0; + } + + if (cells == 2) + return be64dec(prop->data); + else if (cells == 1) + return be32dec(prop->data); + + printk(BIOS_ERR, "Illegal FDT integer property size %u @%p\n", prop->size, prop); + return 0; +} + /* * fdt_find_node searches for a node relative to another node * diff --git a/src/commonlib/include/commonlib/device_tree.h b/src/commonlib/include/commonlib/device_tree.h index f51f827593..5ab5fbf294 100644 --- a/src/commonlib/include/commonlib/device_tree.h +++ b/src/commonlib/include/commonlib/device_tree.h @@ -118,6 +118,8 @@ u32 fdt_read_prop(const void *blob, u32 node_offset, const char *prop_name, /* Read reg property and save regions inside 'regions'. Returns number of regions read */ u32 fdt_read_reg_prop(const void *blob, u32 node_offset, u32 addr_cells, u32 size_cells, struct device_tree_region regions[], size_t regions_count); +/* Reads value for a fdt_prop, considering the cells */ +uint64_t fdt_read_int_prop(struct fdt_property *prop, u32 cells); /* Find a node by a given path and return the offset */ u32 fdt_find_node_by_path(const void *blob, const char *path, u32 *addrcp, u32 *sizecp); /* Find multiple nodes matching a given pattern. Returns number of nodes found */