blob: 1828a80bf03177d29a01ea8e198b11328232bf23 [file] [log] [blame]
Louis Mayencourt6d2b5732019-12-17 13:17:25 +00001/*
2 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8
9#include <common/debug.h>
10#include <common/fdt_wrappers.h>
11#include <lib/fconf/fconf_dyn_cfg_getter.h>
12#include <lib/object_pool.h>
13#include <libfdt.h>
14
Manish V Badarkhebb533c72020-06-11 22:17:30 +010015/* We currently use FW, TB_FW, SOC_FW, TOS_FW, NS_fw and HW configs */
16#define MAX_DTB_INFO U(6)
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000017
Manish V Badarkhebb533c72020-06-11 22:17:30 +010018#ifdef IMAGE_BL1
19static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO] = {
20 [0] = {
21 .config_addr = ARM_FW_CONFIG_BASE,
22 .config_max_size = (uint32_t)
23 (ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE),
24 .config_id = FW_CONFIG_ID
25 },
26};
27/* Create an object pool starting at the second element */
28static OBJECT_POOL(dtb_info_pool, &dtb_infos[1],
29 sizeof(struct dyn_cfg_dtb_info_t), MAX_DTB_INFO-1);
30#else
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000031static struct dyn_cfg_dtb_info_t dtb_infos[MAX_DTB_INFO];
32static OBJECT_POOL_ARRAY(dtb_info_pool, dtb_infos);
Manish V Badarkhebb533c72020-06-11 22:17:30 +010033#endif
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000034
35struct dyn_cfg_dtb_info_t *dyn_cfg_dtb_info_getter(unsigned int config_id)
36{
37 unsigned int index;
38 struct dyn_cfg_dtb_info_t *info;
39
40 /* Positions index to the proper config-id */
41 for (index = 0; index < MAX_DTB_INFO; index++) {
42 if (dtb_infos[index].config_id == config_id) {
43 info = &dtb_infos[index];
44 break;
45 }
46 }
47
48 if (index == MAX_DTB_INFO) {
49 WARN("FCONF: Invalid config id %u\n", config_id);
50 info = NULL;
51 }
52
53 return info;
54}
55
56int fconf_populate_dtb_registry(uintptr_t config)
57{
58 int rc;
59 int node, child;
60 struct dyn_cfg_dtb_info_t *dtb_info;
61
62 /* As libfdt use void *, we can't avoid this cast */
63 const void *dtb = (void *)config;
64
Louis Mayencourtb26fafa2020-04-20 14:17:21 +010065 /* Find the node offset point to "fconf,dyn_cfg-dtb_registry" compatible property */
66 const char *compatible_str = "fconf,dyn_cfg-dtb_registry";
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000067 node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
68 if (node < 0) {
69 ERROR("FCONF: Can't find %s compatible in dtb\n", compatible_str);
70 return node;
71 }
72
Manish V Badarkhebb533c72020-06-11 22:17:30 +010073#ifndef IMAGE_BL1
74 /* Save config dtb information */
75 dtb_info = pool_alloc(&dtb_info_pool);
76
77 dtb_info->config_addr = config;
78 dtb_info->config_max_size = fdt_totalsize(dtb);
79 dtb_info->config_id = FW_CONFIG_ID;
80#endif
81
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000082 fdt_for_each_subnode(child, dtb, node) {
Andre Przywarafe5bdf52020-03-26 11:22:37 +000083 uint32_t val32;
84 uint64_t val64;
85
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000086 dtb_info = pool_alloc(&dtb_info_pool);
87
88 /* Read configuration dtb information */
Andre Przywarafe5bdf52020-03-26 11:22:37 +000089 rc = fdt_read_uint64(dtb, child, "load-address", &val64);
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000090 if (rc < 0) {
91 ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
92 return rc;
93 }
Andre Przywarafe5bdf52020-03-26 11:22:37 +000094 dtb_info->config_addr = (uintptr_t)val64;
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000095
Andre Przywarafe5bdf52020-03-26 11:22:37 +000096 rc = fdt_read_uint32(dtb, child, "max-size", &val32);
Louis Mayencourt6d2b5732019-12-17 13:17:25 +000097 if (rc < 0) {
98 ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
99 return rc;
100 }
Andre Przywarafe5bdf52020-03-26 11:22:37 +0000101 dtb_info->config_max_size = val32;
Louis Mayencourt6d2b5732019-12-17 13:17:25 +0000102
Andre Przywarafe5bdf52020-03-26 11:22:37 +0000103 rc = fdt_read_uint32(dtb, child, "id", &val32);
Louis Mayencourt6d2b5732019-12-17 13:17:25 +0000104 if (rc < 0) {
105 ERROR("FCONF: Incomplete configuration property in dtb-registry.\n");
106 return rc;
107 }
Andre Przywarafe5bdf52020-03-26 11:22:37 +0000108 dtb_info->config_id = val32;
Louis Mayencourt6d2b5732019-12-17 13:17:25 +0000109
110 VERBOSE("FCONF: dyn_cfg.dtb_registry cell found with:\n");
111 VERBOSE("\tload-address = %lx\n", dtb_info->config_addr);
112 VERBOSE("\tmax-size = 0x%zx\n", dtb_info->config_max_size);
113 VERBOSE("\tconfig-id = %u\n", dtb_info->config_id);
114 }
115
116 if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
117 ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
118 return child;
119 }
120
121 return 0;
122}
123
Manish V Badarkhe64616a52020-05-31 08:53:40 +0100124FCONF_REGISTER_POPULATOR(FW_CONFIG, dyn_cfg, fconf_populate_dtb_registry);