xref: /rk3399_ARM-atf/plat/arm/common/arm_dyn_cfg_helpers.c (revision cab0b5b0452556c9f7ba3fa98c233d3a6a62b023)
1 /*
2  * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <desc_image_load.h>
9 #include <fdt_wrappers.h>
10 #include <libfdt.h>
11 
12 /*******************************************************************************
13  * Helper to read the `hw_config` property in config DTB. This function
14  * expects the following properties to be present in the config DTB.
15  *	name : hw_config_addr		size : 2 cells
16  *	name : hw_config_max_size	size : 1 cell
17  *
18  * Arguments:
19  *	void *dtb		 - pointer to the TB_FW_CONFIG in memory
20  *	int node		 - The node offset to appropriate node in the
21  *					 DTB.
22  *	uint64_t *hw_config_addr - Returns the `hw_config` load address if read
23  *					 is successful.
24  *	uint32_t *hw_config_size - Returns the `hw_config` size if read is
25  *					 successful.
26  *
27  * Returns 0 on success and -1 on error.
28  ******************************************************************************/
29 int arm_dyn_get_hwconfig_info(void *dtb, int node,
30 		uint64_t *hw_config_addr, uint32_t *hw_config_size)
31 {
32 	int err;
33 
34 	assert(dtb);
35 	assert(hw_config_addr);
36 	assert(hw_config_size);
37 
38 	/* Check if the pointer to DT is correct */
39 	assert(fdt_check_header(dtb) == 0);
40 
41 	/* Assert the node offset point to "arm,tb_fw" compatible property */
42 	assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
43 
44 	err = fdtw_read_cells(dtb, node, "hw_config_addr", 2,
45 				(void *) hw_config_addr);
46 	if (err < 0) {
47 		WARN("Read cell failed for hw_config_addr\n");
48 		return -1;
49 	}
50 
51 	err = fdtw_read_cells(dtb, node, "hw_config_max_size", 1,
52 				(void *) hw_config_size);
53 	if (err < 0) {
54 		WARN("Read cell failed for hw_config_max_size\n");
55 		return -1;
56 	}
57 
58 	VERBOSE("Dyn cfg: Read hw_config address from TB_FW_CONFIG 0x%p %p\n",
59 				hw_config_addr, hw_config_size);
60 
61 	return 0;
62 }
63 
64 /*******************************************************************************
65  * Validate the tb_fw_config is a valid DTB file and returns the node offset
66  * to "arm,tb_fw" property.
67  * Arguments:
68  *	void *dtb - pointer to the TB_FW_CONFIG in memory
69  *	int *node - Returns the node offset to "arm,tb_fw" property if found.
70  *
71  * Returns 0 on success and -1 on error.
72  ******************************************************************************/
73 int arm_dyn_tb_fw_cfg_init(void *dtb, int *node)
74 {
75 	assert(dtb);
76 	assert(node);
77 
78 	/* Check if the pointer to DT is correct */
79 	if (fdt_check_header(dtb) != 0) {
80 		WARN("Invalid DTB file passed as TB_FW_CONFIG\n");
81 		return -1;
82 	}
83 
84 	/* Assert the node offset point to "arm,tb_fw" compatible property */
85 	*node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw");
86 	if (*node < 0) {
87 		WARN("The compatible property `arm,tb_fw` not found in the config\n");
88 		return -1;
89 	}
90 
91 	VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n");
92 	return 0;
93 }
94