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