xref: /rk3399_ARM-atf/plat/amd/common/plat_xfer_list.c (revision 06f3c7058c42a9f1a9f7df75ea2de71a000855e8)
1 /*
2  * Copyright (c) 2023-2025, Advanced Micro Devices, Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <stddef.h>
7 #include <arch_helpers.h>
8 #include <common/debug.h>
9 #include <lib/transfer_list.h>
10 #include <platform_def.h>
11 
12 
13 static struct transfer_list_header *tl_hdr;
14 static int32_t tl_ops_holder;
15 
16 bool populate_data_from_xfer_list(void)
17 {
18 	bool ret = true;
19 
20 	tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
21 	tl_ops_holder = transfer_list_check_header(tl_hdr);
22 
23 	if ((tl_ops_holder != TL_OPS_ALL) && (tl_ops_holder != TL_OPS_RO)) {
24 		ret = false;
25 	}
26 
27 	return ret;
28 }
29 
30 int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
31 				       entry_point_info_t *bl33)
32 {
33 	int32_t ret = tl_ops_holder;
34 	struct transfer_list_entry *te = NULL;
35 	struct entry_point_info *ep = NULL;
36 
37 	if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
38 		transfer_list_dump(tl_hdr);
39 		while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
40 			ep = transfer_list_entry_data(te);
41 			if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
42 				switch (GET_SECURITY_STATE(ep->h.attr)) {
43 				case NON_SECURE:
44 					*bl33 = *ep;
45 					continue;
46 				case SECURE:
47 					*bl32 = *ep;
48 #if defined(SPD_opteed)
49 					/*
50 					 * Populate the args expected by opteed,
51 					 * arg0 - dt address,
52 					 * arg1 - Xfer List Convention Version,
53 					 * arg3 - Xfer List address
54 					 * remaining args are set to 0.
55 					 */
56 					if (transfer_list_set_handoff_args(tl_hdr, bl32) == NULL) {
57 						ERROR("Invalid transfer list\n");
58 					}
59 #endif /* SPD_opteed */
60 					continue;
61 				default:
62 					ERROR("Unrecognized Image Security State %lu\n",
63 					      GET_SECURITY_STATE(ep->h.attr));
64 					ret = TL_OPS_NON;
65 				}
66 			}
67 		}
68 	}
69 
70 	return ret;
71 }
72 
73 void *transfer_list_retrieve_dt_address(void)
74 {
75 	void *dtb = NULL;
76 	struct transfer_list_entry *te = NULL;
77 
78 	if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
79 		te = transfer_list_find(tl_hdr, TL_TAG_FDT);
80 		if (te != NULL) {
81 			dtb = transfer_list_entry_data(te);
82 		}
83 	}
84 
85 	return dtb;
86 }
87