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