1 /*
2  * Copyright (c) 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 
12 #include <libfdt.h>
13 
14 #include <plat/arm/common/fconf_nv_cntr_getter.h>
15 
16 /*******************************************************************************
17  * fconf_populate_cot_descs() - Populate available nv-counters and update global
18  *				structure.
19  * @config[in]:	Pointer to the device tree blob in memory
20  *
21  * Return 0 on success or an error value otherwise.
22  ******************************************************************************/
fconf_populate_nv_cntrs(uintptr_t config)23 static int fconf_populate_nv_cntrs(uintptr_t config)
24 {
25 	int rc, node, child;
26 	uint32_t id;
27 	uintptr_t reg;
28 
29 	/* As libfdt uses void *, we can't avoid this cast */
30 	const void *dtb = (void *)config;
31 	const char *compatible_str = "arm, non-volatile-counter";
32 
33 	node = fdt_node_offset_by_compatible(dtb, -1, compatible_str);
34 	if (node < 0) {
35 		ERROR("FCONF: Can't find %s compatible in node\n",
36 			compatible_str);
37 		return node;
38 	}
39 
40 	fdt_for_each_subnode(child, dtb, node) {
41 
42 		rc = fdt_read_uint32(dtb, child, "id", &id);
43 		if (rc < 0) {
44 			ERROR("FCONF: Can't find %s property in node\n", "id");
45 			return rc;
46 		}
47 
48 		assert(id < MAX_NV_CTR_IDS);
49 
50 		rc = fdt_get_reg_props_by_index(dtb, child, 0, &reg, NULL);
51 		if (rc < 0) {
52 			ERROR("FCONF: Can't find %s property in node\n", "reg");
53 			return rc;
54 		}
55 
56 		nv_cntr_base_addr[id] = reg;
57 	}
58 
59 	return 0;
60 }
61 
62 FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs);
63