diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index ca5b4556d..842d71339 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -15,90 +15,72 @@ #include /* - * Read cells from a given property of the given node. At most 2 cells of the - * property are read, and pointer is updated. Returns 0 on success, and -1 upon - * error + * Read cells from a given property of the given node. Any number of 32-bit + * cells of the property can be read. Returns 0 on success, or a negative + * FDT error value otherwise. */ -int fdtw_read_cells(const void *dtb, int node, const char *prop, - unsigned int cells, void *value) +int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, + unsigned int cells, uint32_t *value) { - const uint32_t *value_ptr; - uint32_t hi = 0, lo; + const fdt32_t *prop; int value_len; assert(dtb != NULL); - assert(prop != NULL); + assert(prop_name != NULL); assert(value != NULL); assert(node >= 0); - /* We expect either 1 or 2 cell property */ - assert(cells <= 2U); - /* Access property and obtain its length (in bytes) */ - value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), - &value_len); - if (value_ptr == NULL) { - WARN("Couldn't find property %s in dtb\n", prop); - return -1; + prop = fdt_getprop(dtb, node, prop_name, &value_len); + if (prop == NULL) { + WARN("Couldn't find property %s in dtb\n", prop_name); + return -FDT_ERR_NOTFOUND; } - /* Verify that property length accords with cell length */ - if (NCELLS((unsigned int)value_len) != cells) { + /* Verify that property length can fill the entire array. */ + if (NCELLS((unsigned int)value_len) < cells) { WARN("Property length mismatch\n"); - return -1; + return -FDT_ERR_BADVALUE; } - if (cells == 2U) { - hi = fdt32_to_cpu(*value_ptr); - value_ptr++; + for (unsigned int i = 0U; i < cells; i++) { + value[i] = fdt32_to_cpu(prop[i]); } - lo = fdt32_to_cpu(*value_ptr); - - if (cells == 2U) - *((uint64_t *) value) = ((uint64_t) hi << 32) | lo; - else - *((uint32_t *) value) = lo; - return 0; } -/* - * Read cells from a given property of the given node. Any number of 32-bit - * cells of the property can be read. The fdt pointer is updated. Returns 0 on - * success, and -1 on error. - */ -int fdtw_read_array(const void *dtb, int node, const char *prop, - unsigned int cells, void *value) +int fdt_read_uint32(const void *dtb, int node, const char *prop_name, + uint32_t *value) { - const uint32_t *value_ptr; - int value_len; + return fdt_read_uint32_array(dtb, node, prop_name, 1, value); +} - assert(dtb != NULL); - assert(prop != NULL); - assert(value != NULL); - assert(node >= 0); +uint32_t fdt_read_uint32_default(const void *dtb, int node, + const char *prop_name, uint32_t dflt_value) +{ + uint32_t ret = dflt_value; + int err = fdt_read_uint32(dtb, node, prop_name, &ret); - /* Access property and obtain its length (in bytes) */ - value_ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop), - &value_len); - if (value_ptr == NULL) { - WARN("Couldn't find property %s in dtb\n", prop); - return -1; + if (err < 0) { + return dflt_value; } - /* Verify that property length accords with cell length */ - if (NCELLS((unsigned int)value_len) != cells) { - WARN("Property length mismatch\n"); - return -1; - } - - uint32_t *dst = value; - - for (unsigned int i = 0U; i < cells; i++) { - dst[i] = fdt32_to_cpu(value_ptr[i]); + return ret; +} + +int fdt_read_uint64(const void *dtb, int node, const char *prop_name, + uint64_t *value) +{ + uint32_t array[2] = {0, 0}; + int ret; + + ret = fdt_read_uint32_array(dtb, node, prop_name, 2, array); + if (ret < 0) { + return ret; } + *value = ((uint64_t)array[0] << 32) | array[1]; return 0; } @@ -244,3 +226,53 @@ int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop, return err; } + +static uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells) +{ + uint64_t reg = fdt32_to_cpu(prop[0]); + + if (nr_cells > 1) { + reg = (reg << 32) | fdt32_to_cpu(prop[1]); + } + + return reg; +} + +int fdt_get_reg_props_by_index(const void *dtb, int node, int index, + uintptr_t *base, size_t *size) +{ + const fdt32_t *prop; + int parent, len; + int ac, sc; + int cell; + + parent = fdt_parent_offset(dtb, node); + if (parent < 0) { + return -FDT_ERR_BADOFFSET; + } + + ac = fdt_address_cells(dtb, parent); + sc = fdt_size_cells(dtb, parent); + + cell = index * (ac + sc); + + prop = fdt_getprop(dtb, node, "reg", &len); + if (prop == NULL) { + WARN("Couldn't find \"reg\" property in dtb\n"); + return -FDT_ERR_NOTFOUND; + } + + if (((cell + ac + sc) * (int)sizeof(uint32_t)) > len) { + return -FDT_ERR_BADVALUE; + } + + if (base != NULL) { + *base = (uintptr_t)fdt_read_prop_cells(&prop[cell], ac); + } + + if (size != NULL) { + *size = (size_t)fdt_read_prop_cells(&prop[cell + ac], sc); + } + + return 0; +} diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c index 0cc87cc71..540c66aa3 100644 --- a/drivers/st/clk/stm32mp1_clk.c +++ b/drivers/st/clk/stm32mp1_clk.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1239,7 +1240,8 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, uintptr_t clksrc_address = rcc_base + (clksrc >> 4); unsigned long refclk; uint32_t ifrge = 0U; - uint32_t src, value, fracv; + uint32_t src, value, fracv = 0; + void *fdt; /* Check PLL output */ if (mmio_read_32(pllxcr) != RCC_PLLNCR_PLLON) { @@ -1278,7 +1280,9 @@ static bool stm32mp1_check_pll_conf(enum stm32mp1_pll_id pll_id, } /* Fractional configuration */ - fracv = fdt_read_uint32_default(plloff, "frac", 0); + if (fdt_get_address(&fdt) == 1) { + fracv = fdt_read_uint32_default(fdt, plloff, "frac", 0); + } value = fracv << RCC_PLLNFRACR_FRACV_SHIFT; value |= RCC_PLLNFRACR_FRACLE; @@ -1600,20 +1604,25 @@ int stm32mp1_clk_init(void) bool pll4_preserve = false; bool pll4_bootrom = false; const fdt32_t *pkcs_cell; + void *fdt; + + if (fdt_get_address(&fdt) == 0) { + return false; + } /* Check status field to disable security */ if (!fdt_get_rcc_secure_status()) { mmio_write_32(rcc_base + RCC_TZCR, 0); } - ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc, - (uint32_t)CLKSRC_NB); + ret = fdt_rcc_read_uint32_array("st,clksrc", (uint32_t)CLKSRC_NB, + clksrc); if (ret < 0) { return -FDT_ERR_NOTFOUND; } - ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv, - (uint32_t)CLKDIV_NB); + ret = fdt_rcc_read_uint32_array("st,clkdiv", (uint32_t)CLKDIV_NB, + clkdiv); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1628,8 +1637,8 @@ int stm32mp1_clk_init(void) continue; } - ret = fdt_read_uint32_array(plloff[i], "cfg", - pllcfg[i], (int)PLLCFG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "cfg", + (int)PLLCFG_NB, pllcfg[i]); if (ret < 0) { return -FDT_ERR_NOTFOUND; } @@ -1794,14 +1803,14 @@ int stm32mp1_clk_init(void) continue; } - fracv = fdt_read_uint32_default(plloff[i], "frac", 0); + fracv = fdt_read_uint32_default(fdt, plloff[i], "frac", 0); ret = stm32mp1_pll_config(i, pllcfg[i], fracv); if (ret != 0) { return ret; } - ret = fdt_read_uint32_array(plloff[i], "csg", csg, - (uint32_t)PLLCSG_NB); + ret = fdt_read_uint32_array(fdt, plloff[i], "csg", + (uint32_t)PLLCSG_NB, csg); if (ret == 0) { stm32mp1_pll_csg(i, csg); } else if (ret != -FDT_ERR_NOTFOUND) { diff --git a/drivers/st/clk/stm32mp_clkfunc.c b/drivers/st/clk/stm32mp_clkfunc.c index 87c8e2b84..e87ab1ba7 100644 --- a/drivers/st/clk/stm32mp_clkfunc.c +++ b/drivers/st/clk/stm32mp_clkfunc.c @@ -10,6 +10,7 @@ #include +#include #include #include @@ -150,7 +151,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, continue; } - return fdt_read_uint32_default(subnode, prop_name, dflt_value); + return fdt_read_uint32_default(fdt, subnode, prop_name, + dflt_value); } return dflt_value; @@ -200,8 +202,8 @@ uint32_t fdt_rcc_read_addr(void) * @param count: number of parameters to be read * @return: 0 on succes or a negative value on error */ -int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count) +int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array) { int node; void *fdt; @@ -215,7 +217,7 @@ int fdt_rcc_read_uint32_array(const char *prop_name, return -FDT_ERR_NOTFOUND; } - return fdt_read_uint32_array(node, prop_name, array, count); + return fdt_read_uint32_array(fdt, node, prop_name, count, array); } /* diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c index 40cd4554f..b21c8949f 100644 --- a/drivers/st/ddr/stm32mp1_ram.c +++ b/drivers/st/ddr/stm32mp1_ram.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -205,13 +206,13 @@ static int stm32mp1_ddr_setup(void) return -EINVAL; } - config.info.speed = fdt_read_uint32_default(node, "st,mem-speed", 0); - if (!config.info.speed) { + ret = fdt_read_uint32(fdt, node, "st,mem-speed", &config.info.speed); + if (ret < 0) { VERBOSE("%s: no st,mem-speed\n", __func__); return -EINVAL; } - config.info.size = fdt_read_uint32_default(node, "st,mem-size", 0); - if (!config.info.size) { + ret = fdt_read_uint32(fdt, node, "st,mem-size", &config.info.size); + if (ret < 0) { VERBOSE("%s: no st,mem-size\n", __func__); return -EINVAL; } @@ -223,10 +224,10 @@ static int stm32mp1_ddr_setup(void) INFO("RAM: %s\n", config.info.name); for (idx = 0; idx < ARRAY_SIZE(param); idx++) { - ret = fdt_read_uint32_array(node, param[idx].name, + ret = fdt_read_uint32_array(fdt, node, param[idx].name, + param[idx].size, (void *)((uintptr_t)&config + - param[idx].offset), - param[idx].size); + param[idx].offset)); VERBOSE("%s: %s[0x%x] = %d\n", __func__, param[idx].name, param[idx].size, ret); diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index f467958b7..7a6b59893 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -12,10 +12,14 @@ /* Number of cells, given total length in bytes. Each cell is 4 bytes long */ #define NCELLS(len) ((len) / 4U) -int fdtw_read_cells(const void *dtb, int node, const char *prop, - unsigned int cells, void *value); -int fdtw_read_array(const void *dtb, int node, const char *prop, - unsigned int cells, void *value); +int fdt_read_uint32(const void *dtb, int node, const char *prop_name, + uint32_t *value); +uint32_t fdt_read_uint32_default(const void *dtb, int node, + const char *prop_name, uint32_t dflt_value); +int fdt_read_uint64(const void *dtb, int node, const char *prop_name, + uint64_t *value); +int fdt_read_uint32_array(const void *dtb, int node, const char *prop_name, + unsigned int cells, uint32_t *value); int fdtw_read_string(const void *dtb, int node, const char *prop, char *str, size_t size); int fdtw_write_inplace_cells(void *dtb, int node, const char *prop, @@ -24,5 +28,7 @@ int fdtw_read_bytes(const void *dtb, int node, const char *prop, unsigned int length, void *value); int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop, unsigned int length, const void *data); +int fdt_get_reg_props_by_index(const void *dtb, int node, int index, + uintptr_t *base, size_t *size); #endif /* FDT_WRAPPERS_H */ diff --git a/include/drivers/st/stm32mp_clkfunc.h b/include/drivers/st/stm32mp_clkfunc.h index 076916730..0902f445d 100644 --- a/include/drivers/st/stm32mp_clkfunc.h +++ b/include/drivers/st/stm32mp_clkfunc.h @@ -21,8 +21,8 @@ uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id, int fdt_get_rcc_node(void *fdt); uint32_t fdt_rcc_read_addr(void); -int fdt_rcc_read_uint32_array(const char *prop_name, - uint32_t *array, uint32_t count); +int fdt_rcc_read_uint32_array(const char *prop_name, uint32_t count, + uint32_t *array); int fdt_rcc_subnode_offset(const char *name); const fdt32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp); bool fdt_get_rcc_secure_status(void); diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index 317d3e5d3..03aaf9bb6 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -57,26 +57,32 @@ int fconf_populate_dtb_registry(uintptr_t config) } fdt_for_each_subnode(child, dtb, node) { + uint32_t val32; + uint64_t val64; + dtb_info = pool_alloc(&dtb_info_pool); /* Read configuration dtb information */ - rc = fdtw_read_cells(dtb, child, "load-address", 2, &dtb_info->config_addr); + rc = fdt_read_uint64(dtb, child, "load-address", &val64); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_addr = (uintptr_t)val64; - rc = fdtw_read_cells(dtb, child, "max-size", 1, &dtb_info->config_max_size); + rc = fdt_read_uint32(dtb, child, "max-size", &val32); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_max_size = val32; - rc = fdtw_read_cells(dtb, child, "id", 1, &dtb_info->config_id); + rc = fdt_read_uint32(dtb, child, "id", &val32); if (rc < 0) { ERROR("FCONF: Incomplete configuration property in dtb-registry.\n"); return rc; } + dtb_info->config_id = val32; VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n"); VERBOSE("\tload-address = %lx\n", dtb_info->config_addr); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index a4d61d8cd..21278019e 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -17,6 +17,8 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) { int err; int node; + uint64_t val64; + uint32_t val32; /* As libfdt use void *, we can't avoid this cast */ const void *dtb = (void *)config; @@ -30,7 +32,7 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) } /* Locate the disable_auth cell and read the value */ - err = fdtw_read_cells(dtb, node, "disable_auth", 1, &tbbr_dyn_config.disable_auth); + err = fdt_read_uint32(dtb, node, "disable_auth", &tbbr_dyn_config.disable_auth); if (err < 0) { WARN("FCONF: Read cell failed for `disable_auth`\n"); return err; @@ -48,19 +50,19 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) #endif /* Retrieve the Mbed TLS heap details from the DTB */ - err = fdtw_read_cells(dtb, node, - "mbedtls_heap_addr", 2, &tbbr_dyn_config.mbedtls_heap_addr); + err = fdt_read_uint64(dtb, node, "mbedtls_heap_addr", &val64); if (err < 0) { ERROR("FCONF: Read cell failed for mbedtls_heap\n"); return err; } + tbbr_dyn_config.mbedtls_heap_addr = (void *)(uintptr_t)val64; - err = fdtw_read_cells(dtb, node, - "mbedtls_heap_size", 1, &tbbr_dyn_config.mbedtls_heap_size); + err = fdt_read_uint32(dtb, node, "mbedtls_heap_size", &val32); if (err < 0) { ERROR("FCONF: Read cell failed for mbedtls_heap\n"); return err; } + tbbr_dyn_config.mbedtls_heap_size = val32; VERBOSE("FCONF:tbbr.disable_auth cell found with value = %d\n", tbbr_dyn_config.disable_auth); diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c index 2952cde80..f1d9b93f7 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -18,7 +18,7 @@ int fconf_populate_gicv3_config(uintptr_t config) { int err; int node; - int addr[20]; + uintptr_t addr; /* Necessary to work with libfdt APIs */ const void *hw_config_dtb = (const void *)config; @@ -33,26 +33,32 @@ int fconf_populate_gicv3_config(uintptr_t config) WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n"); return 0; } - /* Read the reg cell holding base address of GIC controller modules - A sample reg cell array is shown here: - reg = <0x0 0x2f000000 0 0x10000>, // GICD - <0x0 0x2f100000 0 0x200000>, // GICR - <0x0 0x2c000000 0 0x2000>, // GICC - <0x0 0x2c010000 0 0x2000>, // GICH - <0x0 0x2c02f000 0 0x2000>; // GICV - */ - - err = fdtw_read_array(hw_config_dtb, node, "reg", 20, &addr); + /* The GICv3 DT binding holds at least two address/size pairs, + * the first describing the distributor, the second the redistributors. + * See: bindings/interrupt-controller/arm,gic-v3.yaml + */ + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0, &addr, NULL); if (err < 0) { - ERROR("FCONF: Failed to read reg property of GIC node\n"); + ERROR("FCONF: Failed to read GICD reg property of GIC node\n"); + return err; } + gicv3_config.gicd_base = addr; + + err = fdt_get_reg_props_by_index(hw_config_dtb, node, 1, &addr, NULL); + if (err < 0) { + ERROR("FCONF: Failed to read GICR reg property of GIC node\n"); + } else { + gicv3_config.gicr_base = addr; + } + return err; } int fconf_populate_topology(uintptr_t config) { - int err, node, cluster_node, core_node, thread_node, max_pwr_lvl = 0; + int err, node, cluster_node, core_node, thread_node; uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0; + uint32_t max_pwr_lvl = 0; /* Necessary to work with libfdt APIs */ const void *hw_config_dtb = (const void *)config; @@ -64,7 +70,7 @@ int fconf_populate_topology(uintptr_t config) return node; } - err = fdtw_read_cells(hw_config_dtb, node, "max-pwr-lvl", 1, &max_pwr_lvl); + err = fdt_read_uint32(hw_config_dtb, node, "max-pwr-lvl", &max_pwr_lvl); if (err < 0) { /* * Some legacy FVP dts may not have this property. Assign the default @@ -74,7 +80,7 @@ int fconf_populate_topology(uintptr_t config) max_pwr_lvl = 2; } - assert((uint32_t)max_pwr_lvl <= MPIDR_AFFLVL2); + assert(max_pwr_lvl <= MPIDR_AFFLVL2); /* Find the offset of the "cpus" node */ node = fdt_path_offset(hw_config_dtb, "/cpus"); @@ -156,7 +162,7 @@ int fconf_populate_topology(uintptr_t config) return -1; } - soc_topology.plat_max_pwr_level = (uint32_t)max_pwr_lvl; + soc_topology.plat_max_pwr_level = max_pwr_lvl; soc_topology.plat_cluster_count = cluster_count; soc_topology.cluster_cpu_count = max_cpu_per_cluster; soc_topology.plat_cpu_count = total_cpu_count; diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index cab832f68..a9e569e78 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -15,8 +15,8 @@ #define hw_config__topology_getter(prop) soc_topology.prop struct gicv3_config_t { - void *gicd_base; - void *gicr_base; + uintptr_t gicd_base; + uintptr_t gicr_base; }; struct hw_topology_t { diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index 0c93d0aab..50a5ba4d9 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -15,6 +15,7 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header @@ -24,6 +25,9 @@ fdt fdt_first_subnode fdt fdt_next_subnode fdt fdt_path_offset fdt fdt_subnode_offset +fdt fdt_address_cells +fdt fdt_size_cells +fdt fdt_parent_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index b1b9ed463..eb4399ec0 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -15,6 +15,7 @@ # fdt fdt_getprop_namelen patch rom rom_lib_init +fdt fdt_getprop fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header @@ -22,6 +23,7 @@ fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode +fdt fdt_parent_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index 6ebc467ed..26e51b2a3 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -241,7 +241,8 @@ int fconf_populate_arm_io_policies(uintptr_t config) /* Locate the uuid cells and read the value for all the load info uuid */ for (i = 0; i < FCONF_ARM_IO_UUID_NUMBER; i++) { uuid_ptr = pool_alloc(&fconf_arm_uuids_pool); - err = fdtw_read_array(dtb, node, load_info[i].name, 4, &uuid_helper.word); + err = fdt_read_uint32_array(dtb, node, load_info[i].name, + 4, uuid_helper.word); if (err < 0) { WARN("FCONF: Read cell failed for %s\n", load_info[i].name); return err; diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index 9b6fa9b1f..1b09bc8e5 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -29,6 +29,7 @@ int fconf_populate_arm_sp(uintptr_t config) int sp_node, node, err; union uuid_helper_t uuid_helper; unsigned int index = 0; + uint32_t val32; const unsigned int sp_start_index = MAX_NUMBER_IDS - MAX_SP_IDS; /* As libfdt use void *, we can't avoid this cast */ @@ -44,8 +45,8 @@ int fconf_populate_arm_sp(uintptr_t config) } fdt_for_each_subnode(sp_node, dtb, node) { - err = fdtw_read_array(dtb, sp_node, "uuid", 4, - &uuid_helper.word); + err = fdt_read_uint32_array(dtb, sp_node, "uuid", 4, + uuid_helper.word); if (err < 0) { ERROR("FCONF: cannot read SP uuid\n"); return -1; @@ -53,12 +54,12 @@ int fconf_populate_arm_sp(uintptr_t config) arm_sp.uuids[index] = uuid_helper; - err = fdtw_read_cells(dtb, sp_node, "load-address", 1, - &arm_sp.load_addr[index]); + err = fdt_read_uint32(dtb, sp_node, "load-address", &val32); if (err < 0) { ERROR("FCONF: cannot read SP load address\n"); return -1; } + arm_sp.load_addr[index] = val32; VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", __func__, diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index f0aa27cfb..8330356ae 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -21,41 +21,43 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, const void *fdt, int node) { + uint32_t val32; int rc = 0; assert(attr && fdt); - rc = fdtw_read_cells(fdt, node, "maj_ver", 1, &attr->major_version); + rc = fdt_read_uint32(fdt, node, "maj_ver", &attr->major_version); if (rc) { ERROR("Missing SPCI major version in SPM core manifest.\n"); return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "min_ver", 1, &attr->minor_version); + rc = fdt_read_uint32(fdt, node, "min_ver", &attr->minor_version); if (rc) { ERROR("Missing SPCI minor version in SPM core manifest.\n"); return -ENOENT; } - rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); + rc = fdt_read_uint32(fdt, node, "spmc_id", &val32); if (rc) { ERROR("Missing SPMC ID in manifest.\n"); return -ENOENT; } + attr->spmc_id = val32; - rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); + rc = fdt_read_uint32(fdt, node, "exec_state", &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); + rc = fdt_read_uint32(fdt, node, "binary_size", &attr->binary_size); if (rc) NOTICE("Binary size not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); + rc = fdt_read_uint64(fdt, node, "load_address", &attr->load_address); if (rc) NOTICE("Load address not specified in SPM core manifest.\n"); - rc = fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); + rc = fdt_read_uint64(fdt, node, "entrypoint", &attr->entrypoint); if (rc) NOTICE("Entrypoint not specified in SPM core manifest.\n"); diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h index a29d9148d..91a8d67c8 100644 --- a/plat/st/common/include/stm32mp_dt.h +++ b/plat/st/common/include/stm32mp_dt.h @@ -28,10 +28,6 @@ int dt_open_and_check(void); int fdt_get_address(void **fdt_addr); bool fdt_check_node(int node); uint8_t fdt_get_status(int node); -uint32_t fdt_read_uint32_default(int node, const char *prop_name, - uint32_t dflt_value); -int fdt_read_uint32_array(int node, const char *prop_name, - uint32_t *array, uint32_t count); int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base, size_t *size); int dt_set_stdout_pinctrl(void); diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c index acb323cf2..c76b03358 100644 --- a/plat/st/common/stm32mp_dt.c +++ b/plat/st/common/stm32mp_dt.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -134,59 +135,6 @@ static int fdt_get_node_parent_size_cells(int node) } #endif -/******************************************************************************* - * This function reads a value of a node property (generic use of fdt - * library). - * Returns value if success, and a default value if property not found. - * Default value is passed as parameter. - ******************************************************************************/ -uint32_t fdt_read_uint32_default(int node, const char *prop_name, - uint32_t dflt_value) -{ - const fdt32_t *cuint; - int lenp; - - cuint = fdt_getprop(fdt, node, prop_name, &lenp); - if (cuint == NULL) { - return dflt_value; - } - - return fdt32_to_cpu(*cuint); -} - -/******************************************************************************* - * This function reads a series of parameters in a node property - * (generic use of fdt library). - * It reads the values inside the device tree, from property name and node. - * The number of parameters is also indicated as entry parameter. - * Returns 0 on success and a negative FDT error code on failure. - * If success, values are stored at the third parameter address. - ******************************************************************************/ -int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array, - uint32_t count) -{ - const fdt32_t *cuint; - int len; - uint32_t i; - - cuint = fdt_getprop(fdt, node, prop_name, &len); - if (cuint == NULL) { - return -FDT_ERR_NOTFOUND; - } - - if ((uint32_t)len != (count * sizeof(uint32_t))) { - return -FDT_ERR_BADLAYOUT; - } - - for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) { - *array = fdt32_to_cpu(*cuint); - array++; - cuint++; - } - - return 0; -} - /******************************************************************************* * This function fills reg node info (base & size) with an index found by * checking the reg-names node. @@ -375,7 +323,7 @@ uint32_t dt_get_ddr_size(void) return 0; } - return fdt_read_uint32_default(node, "st,mem-size", 0); + return fdt_read_uint32_default(fdt, node, "st,mem-size", 0); } /******************************************************************************* @@ -396,7 +344,7 @@ uintptr_t dt_get_ddrctrl_base(void) assert((fdt_get_node_parent_address_cells(node) == 1) && (fdt_get_node_parent_size_cells(node) == 1)); - if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { return 0; } @@ -421,7 +369,7 @@ uintptr_t dt_get_ddrphyc_base(void) assert((fdt_get_node_parent_address_cells(node) == 1) && (fdt_get_node_parent_size_cells(node) == 1)); - if (fdt_read_uint32_array(node, "reg", array, 4) < 0) { + if (fdt_read_uint32_array(fdt, node, "reg", 4, array) < 0) { return 0; } diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index 5ce7a9c4f..b0ba82abf 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -62,7 +62,8 @@ DTC_FLAGS += -Wno-unit_address_vs_reg include lib/libfdt/libfdt.mk -PLAT_BL_COMMON_SOURCES := plat/st/common/stm32mp_common.c \ +PLAT_BL_COMMON_SOURCES := common/fdt_wrappers.c \ + plat/st/common/stm32mp_common.c \ plat/st/stm32mp1/stm32mp1_private.c PLAT_BL_COMMON_SOURCES += drivers/st/uart/aarch32/stm32_console.S