xref: /rk3399_ARM-atf/plat/amd/common/plat_fdt.c (revision b67e984664a8644d6cfd1812cabaa02cf24f09c9)
1 /*
2  * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <common/debug.h>
7 #include <common/fdt_fixup.h>
8 #include <common/fdt_wrappers.h>
9 #include <libfdt.h>
10 #include <platform_def.h>
11 
12 #include <plat_fdt.h>
13 #ifdef TRANSFER_LIST
14 #include <plat_xfer_list.h>
15 #endif
16 
17 #define FIT_CONFS_PATH	"/configurations"
18 
19 static struct reserve_mem_range rsvnodes[MAX_RESERVE_ADDR_INDICES] = {};
20 static uint32_t rsv_count;
21 
22 static bool is_fit_image(void *dtb)
23 {
24 	int64_t confs_noffset = 0;
25 	bool status = true;
26 
27 	confs_noffset = fdt_path_offset(dtb, FIT_CONFS_PATH);
28 
29 	/* confs_noffset is only present on FIT image */
30 	if (confs_noffset < 0) {
31 		status = false;
32 	}
33 
34 	return status;
35 }
36 
37 int32_t is_valid_dtb(void *fdt)
38 {
39 	int32_t ret = 0;
40 
41 	ret = fdt_check_header(fdt);
42 	if (ret != 0) {
43 		ERROR("Can't read DT at %p\n", fdt);
44 		goto error;
45 	}
46 
47 	ret = fdt_open_into(fdt, fdt, XILINX_OF_BOARD_DTB_MAX_SIZE);
48 	if (ret < 0) {
49 		ERROR("Invalid Device Tree at %p: error %d\n", fdt, ret);
50 		goto error;
51 	}
52 
53 	if (is_fit_image(fdt)) {
54 		WARN("FIT image detected, TF-A will not update DTB for DDR address space\n");
55 		ret = -FDT_ERR_NOTFOUND;
56 	}
57 error:
58 	return ret;
59 }
60 
61 /* TODO: Reserve TFA memory in DT through custom TL entry */
62 void prepare_dtb(void)
63 {
64 
65 }
66 
67 uintptr_t plat_retrieve_dt_addr(void)
68 {
69 	void *dtb = NULL;
70 
71 	dtb = transfer_list_retrieve_dt_address();
72 	if (dtb == NULL) {
73 		WARN("TL header or DT entry is invalid\n");
74 	}
75 
76 	return (uintptr_t)dtb;
77 }
78 
79 struct reserve_mem_range *get_reserved_entries_fdt(uint32_t *reserve_nodes)
80 {
81 	struct reserve_mem_range *rsvmr = NULL;
82 
83 	if ((rsv_count > 0) && (reserve_nodes != NULL)) {
84 		rsvmr = &rsvnodes[0];
85 		*reserve_nodes = rsv_count;
86 	}
87 
88 	return rsvmr;
89 }
90 
91 /* TODO: Parse TL overlays for updated tf-a and op-tee reserved nodes */
92 uint32_t retrieve_reserved_entries(void)
93 {
94 	uint32_t ret = 1;
95 	void *dtb = NULL;
96 	int offset, node;
97 	uint32_t i = 0;
98 	const fdt32_t *reg_prop;
99 
100 
101 	/* Get DT blob address */
102 	dtb = (void *)plat_retrieve_dt_addr();
103 
104 	/* Check if DT is valid */
105 	if (is_valid_dtb(dtb) >= 0) {
106 		/* Find reserved memory node */
107 		offset = fdt_path_offset(dtb, "/reserved-memory");
108 		if (offset >= 0) {
109 
110 			/* Parse subnodes of reserved-memory */
111 			fdt_for_each_subnode(node, dtb, offset) {
112 				if (fdt_getprop(dtb, node, "no-map", NULL) == NULL) {
113 					continue;
114 				}
115 
116 				if (rsv_count == MAX_RESERVE_ADDR_INDICES) {
117 					break;
118 				}
119 
120 				reg_prop = fdt_getprop(dtb, node, "reg", NULL);
121 				if (reg_prop == NULL) {
122 					INFO("No valid reg prop found for subnode\n");
123 					continue;
124 				}
125 
126 				rsvnodes[i].base = (((uint64_t)fdt32_to_cpu(reg_prop[0]) << 32) |
127 						fdt32_to_cpu(reg_prop[1]));
128 				rsvnodes[i].size = (((uint64_t)fdt32_to_cpu(reg_prop[2]) << 32) |
129 						fdt32_to_cpu(reg_prop[3]));
130 				i++;
131 			}
132 			ret = 0;
133 			rsv_count = i;
134 		}
135 	}
136 
137 	return ret;
138 }
139