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
8 #include <platform_def.h>
9
10 #include <arch_helpers.h>
11 #include <common/debug.h>
12 #include <transfer_list.h>
13
14 static struct transfer_list_header *tl_hdr;
15 static int32_t tl_ops_holder;
16
populate_data_from_xfer_list(void)17 bool populate_data_from_xfer_list(void)
18 {
19 bool ret = true;
20
21 tl_hdr = (struct transfer_list_header *)FW_HANDOFF_BASE;
22 tl_ops_holder = transfer_list_check_header(tl_hdr);
23
24 if ((tl_ops_holder != TL_OPS_ALL) && (tl_ops_holder != TL_OPS_RO)) {
25 ret = false;
26 }
27
28 return ret;
29 }
30
transfer_list_populate_ep_info(entry_point_info_t * bl32,entry_point_info_t * bl33)31 int32_t transfer_list_populate_ep_info(entry_point_info_t *bl32,
32 entry_point_info_t *bl33)
33 {
34 int32_t ret = tl_ops_holder;
35 struct transfer_list_entry *te = NULL;
36 struct entry_point_info *ep = NULL;
37
38 if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
39 transfer_list_dump(tl_hdr);
40 while ((te = transfer_list_next(tl_hdr, te)) != NULL) {
41 ep = transfer_list_entry_data(te);
42 if (te->tag_id == TL_TAG_EXEC_EP_INFO64) {
43 switch (GET_SECURITY_STATE(ep->h.attr)) {
44 case NON_SECURE:
45 *bl33 = *ep;
46 break;
47 case SECURE:
48 *bl32 = *ep;
49 #if defined(SPD_opteed)
50 /*
51 * Populate the args expected by opteed,
52 * arg0 - dt address,
53 * arg1 - Xfer List Convention Version,
54 * arg3 - Xfer List address
55 * remaining args are set to 0.
56 */
57 if (transfer_list_set_handoff_args(tl_hdr, bl32) == NULL) {
58 ERROR("Invalid transfer list\n");
59 }
60 #endif /* SPD_opteed */
61 break;
62 default:
63 ERROR("Unrecognized Image Security State %lu\n",
64 GET_SECURITY_STATE(ep->h.attr));
65 ret = TL_OPS_NON;
66 }
67 /*
68 * Clearing the transfer list handoff entry data.
69 */
70 memset(ep, 0, te->data_size);
71
72 if (transfer_list_rem(tl_hdr, te) == false) {
73 INFO("Failed to remove handoff info\n");
74 }
75 }
76 }
77 }
78
79 return ret;
80 }
81
transfer_list_retrieve_dt_address(void)82 void *transfer_list_retrieve_dt_address(void)
83 {
84 void *dtb = NULL;
85 struct transfer_list_entry *te = NULL;
86
87 if ((tl_ops_holder == TL_OPS_ALL) || (tl_ops_holder == TL_OPS_RO)) {
88 te = transfer_list_find(tl_hdr, TL_TAG_FDT);
89 if (te != NULL) {
90 dtb = transfer_list_entry_data(te);
91 }
92 }
93
94 return dtb;
95 }
96