Merge changes from topic "fdt_wrappers_rework" into integration
* changes: arm: fconf: Fix GICv3 dynamic configuration plat/stm32: Implement fdt_read_uint32_default() as a wrapper fdt/wrappers: Replace fdtw_read_cells() implementation plat/stm32: Use generic fdt_read_uint32_array() implementation fdt/wrappers: Generalise fdtw_read_array()
This commit is contained in:
commit
658086747d
|
@ -15,90 +15,72 @@
|
|||
#include <common/fdt_wrappers.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <arch.h>
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <drivers/generic_delay_timer.h>
|
||||
#include <drivers/st/stm32mp_clkfunc.h>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
#include <drivers/st/stm32mp_clkfunc.h>
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/st/stm32mp1_ddr.h>
|
||||
#include <drivers/st/stm32mp1_ddr_helpers.h>
|
||||
#include <drivers/st/stm32mp1_ram.h>
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__,
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <platform_def.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <drivers/st/stm32_gpio.h>
|
||||
#include <drivers/st/stm32mp1_ddr.h>
|
||||
#include <drivers/st/stm32mp1_ram.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue